Project

General

Profile

Download (29.2 KB) Statistics
| Branch: | Tag: | Revision:
1 50d49018 Colin Smith
<?php
2
/*
3 c5d81585 Renato Botelho
 * xmlrpc.php
4 191cb31d Stephen Beaver
 *
5 c5d81585 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 a68f7a3d Luiz Otavio O Souza
 * Copyright (c) 2014-2024 Rubicon Communications, LLC (Netgate)
9 c5d81585 Renato Botelho
 * Copyright (c) 2005 Colin Smith
10
 * All rights reserved.
11 191cb31d Stephen Beaver
 *
12 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15 191cb31d Stephen Beaver
 *
16 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
17 191cb31d Stephen Beaver
 *
18 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23 191cb31d Stephen Beaver
 */
24 50d49018 Colin Smith
25 6b07c15a Matthew Grooms
##|+PRIV
26
##|*IDENT=page-xmlrpclibrary
27 5230f468 jim-p
##|*NAME=XMLRPC Library
28 6b07c15a Matthew Grooms
##|*DESCR=Allow access to the 'XMLRPC Library' page.
29
##|*MATCH=xmlrpc.php*
30
##|-PRIV
31
32 c81ef6e2 Phil Davis
require_once("config.inc");
33
require_once("functions.inc");
34 f81e7cc4 Renato Botelho
require_once("auth.inc");
35 f6339216 jim-p
require_once("filter.inc");
36 c81ef6e2 Phil Davis
require_once("ipsec.inc");
37
require_once("vpn.inc");
38 23fcdccc Viktor G
require_once("openvpn.inc");
39 7cab6335 Renato Botelho
require_once("captiveportal.inc");
40 c81ef6e2 Phil Davis
require_once("shaper.inc");
41 f81e7cc4 Renato Botelho
require_once("XML/RPC2/Server.php");
42 50d49018 Colin Smith
43 f81e7cc4 Renato Botelho
class pfsense_xmlrpc_server {
44 c87f4b70 Ermal
45 f81e7cc4 Renato Botelho
	private $loop_detected = false;
46
	private $remote_addr;
47 c87f4b70 Ermal
48 dc5f639f PiBa-NL
	private function auth() {
49 63d6bb4f Marcos Mendoza
		global $userindex;
50 c472f9a1 jim-p
		$userindex = index_users();
51
52 dc5f639f PiBa-NL
		$username = $_SERVER['PHP_AUTH_USER'];
53
		$password = $_SERVER['PHP_AUTH_PW'];
54 8da3de34 Colin Smith
55 fb1234ab Renato Botelho
		$login_ok = false;
56 f81e7cc4 Renato Botelho
		if (!empty($username) && !empty($password)) {
57
			$attributes = array();
58 63d6bb4f Marcos Mendoza
			$authcfg = auth_get_authserver(config_get_path('system/webgui/authmode'));
59 c3638879 Scott Ullrich
60 f81e7cc4 Renato Botelho
			if (authenticate_user($username, $password,
61
			    $authcfg, $attributes) ||
62
			    authenticate_user($username, $password)) {
63 fb1234ab Renato Botelho
				$login_ok = true;
64 f81e7cc4 Renato Botelho
			}
65
		}
66 3dd2a278 Scott Ullrich
67 fb1234ab Renato Botelho
		if (!$login_ok) {
68 6e0d4751 jim-p
			log_auth(sprintf(gettext("webConfigurator authentication error for user '%1\$s' from: %2\$s"),
69
			    $username,
70
			    $this->remote_addr));
71 137f46d8 Ermal
72 fb1234ab Renato Botelho
			require_once("XML/RPC2/Exception.php");
73
			throw new XML_RPC2_FaultException(gettext(
74
			    'Authentication failed: Invalid username or password'),
75
			    -1);
76
		}
77
78
		$user_entry = getUserEntry($username);
79 1bb9c407 Marcos Mendoza
		$user_entry = $user_entry['item'];
80 fb1234ab Renato Botelho
		/*
81
		 * admin (uid = 0) is allowed
82
		 * or regular user with necessary privilege
83
		 */
84
		if (isset($user_entry['uid']) && $user_entry['uid'] != '0' &&
85
		    !userHasPrivilege($user_entry, 'system-xmlrpc-ha-sync')) {
86
			log_auth("webConfigurator authentication error for '" .
87
			    $username . "' from " . $this->remote_addr .
88
			    " not enough privileges");
89
90
			require_once("XML/RPC2/Exception.php");
91
			throw new XML_RPC2_FaultException(gettext(
92
			    'Authentication failed: not enough privileges'),
93
			    -2);
94
		}
95
96
		return;
97 3dd2a278 Scott Ullrich
	}
98 f81e7cc4 Renato Botelho
99
	private function array_overlay($a1, $a2) {
100
		foreach ($a1 as $k => $v) {
101
			if (!array_key_exists($k, $a2)) {
102
				continue;
103
			}
104
			if (is_array($v) && is_array($a2[$k])) {
105
				$a1[$k] = $this->array_overlay($v, $a2[$k]);
106
			} else {
107
				$a1[$k] = $a2[$k];
108
			}
109
		}
110
111
		return $a1;
112 962f215d Phil Davis
	}
113 c3638879 Scott Ullrich
114 f81e7cc4 Renato Botelho
	public function __construct() {
115 f82f991c Renato Botelho
		$this->remote_addr = $_SERVER['REMOTE_ADDR'];
116 137f46d8 Ermal
117 f81e7cc4 Renato Botelho
		/* grab sync to ip if enabled */
118 63d6bb4f Marcos Mendoza
		if ((config_get_path('hasync/synchronizetoip') !== null) &&
119
		    config_get_path('hasync/synchronizetoip') == $this->remote_addr) {
120 f81e7cc4 Renato Botelho
			$this->loop_detected = true;
121
		}
122 3dd2a278 Scott Ullrich
	}
123 137f46d8 Ermal
124 f81e7cc4 Renato Botelho
	/**
125
	 * Get host version information
126
	 *
127
	 * @return array
128
	 */
129 de3f6463 Reid Linnemann
	public function host_firmware_version($dummy, $timeout) {
130 4f26f187 Viktor G
		ini_set('default_socket_timeout', $timeout);
131 dc5f639f PiBa-NL
		$this->auth();
132 f81e7cc4 Renato Botelho
		return host_firmware_version();
133
	}
134 21dc3a7d Colin Smith
135 f81e7cc4 Renato Botelho
	/**
136
	 * Executes a PHP block of code
137
	 *
138
	 * @param string $code
139
	 *
140
	 * @return bool
141
	 */
142 dc5f639f PiBa-NL
	public function exec_php($code) {
143
		$this->auth();
144 137f46d8 Ermal
145 f81e7cc4 Renato Botelho
		eval($code);
146
		if ($toreturn) {
147
			return $toreturn;
148
		}
149 c87f4b70 Ermal
150 f81e7cc4 Renato Botelho
		return true;
151 3dd2a278 Scott Ullrich
	}
152 137f46d8 Ermal
153 f81e7cc4 Renato Botelho
	/**
154
	 * Executes shell commands
155
	 *
156
	 * @param string $code
157
	 *
158
	 * @return bool
159
	 */
160 dc5f639f PiBa-NL
	public function exec_shell($code) {
161
		$this->auth();
162 50d49018 Colin Smith
163 f81e7cc4 Renato Botelho
		mwexec($code);
164
		return true;
165
	}
166 21dc3a7d Colin Smith
167 f81e7cc4 Renato Botelho
	/**
168
	 * Backup chosen config sections
169
	 *
170
	 * @param array $section
171
	 *
172
	 * @return array
173
	 */
174 dc5f639f PiBa-NL
	public function backup_config_section($section) {
175
		$this->auth();
176 63d6bb4f Marcos Mendoza
		return array_intersect_key(config_get_path(''), array_flip($section));
177 fb0eb20b Ermal
	}
178 c87f4b70 Ermal
179 f81e7cc4 Renato Botelho
	/**
180
	 * Restore defined config section into local config
181
	 *
182
	 * @param array $sections
183
	 *
184
	 * @return bool
185
	 */
186 4f26f187 Viktor G
	public function restore_config_section($sections, $timeout) {
187
		ini_set('default_socket_timeout', $timeout);
188 dc5f639f PiBa-NL
		$this->auth();
189 f81e7cc4 Renato Botelho
190 63d6bb4f Marcos Mendoza
		global $cpzone, $cpzoneid, $old_config;
191 1b99e1e5 jim-p
192 63d6bb4f Marcos Mendoza
		$old_config = config_get_path('');
193 f81e7cc4 Renato Botelho
194
		if ($this->loop_detected) {
195
			log_error("Disallowing CARP sync loop");
196
			return true;
197
		}
198
199
		/*
200
		 * Some sections should just be copied and not merged or we end
201
		 * up unable to sync the deletion of the last item in a section
202
		 */
203
		$sync_full_sections = array(
204
			'aliases',
205
			'ca',
206
			'cert',
207
			'crl',
208
			'dhcpd',
209 30169caa Viktor G
			'dhcrelay',
210
			'dhcrelay6',
211 c9a96f16 Viktor Gurov
			'dnshaper',
212 f81e7cc4 Renato Botelho
			'dnsmasq',
213
			'filter',
214
			'ipsec',
215
			'nat',
216
			'openvpn',
217
			'schedules',
218 c9a96f16 Viktor Gurov
			'shaper',
219 f81e7cc4 Renato Botelho
			'unbound',
220
			'wol',
221
		);
222
223
		$syncd_full_sections = array();
224
225
		foreach ($sync_full_sections as $section) {
226 9bfd8974 jim-p
			/* Do not test for empty here or removing final entry
227
			 * from a section will not work */
228
			if (!array_key_exists($section, $sections)) {
229 f81e7cc4 Renato Botelho
				continue;
230
			}
231
232 9bfd8974 jim-p
			config_set_path($section, array_get_path($sections, $section));
233
			array_del_path($sections, $section);
234 f81e7cc4 Renato Botelho
			$syncd_full_sections[] = $section;
235 1b99e1e5 jim-p
		}
236
237 146b0a43 Augustin-FL
		/* If captive portal sync is enabled on primary node, remove local CP on the secondary */
238 63d6bb4f Marcos Mendoza
		if (is_array($sections['captiveportal'])) {
239 ac0a027f Christian McDonald
			foreach (config_get_path('captiveportal', []) as $zone => $item) {
240 146b0a43 Augustin-FL
				if (!isset($sections['captiveportal'][$zone])) {
241
					$cpzone = $zone;
242 7e3ea4a8 Christian McDonald
					config_del_path("captiveportal/{$cpzone}/enable");
243 63d6bb4f Marcos Mendoza
					captiveportal_configure_zone(config_get_path("captiveportal/{$cpzone}"));
244 7e3ea4a8 Christian McDonald
					config_del_path("captiveportal/{$cpzone}");
245 63d6bb4f Marcos Mendoza
					config_del_path("voucher/{$cpzone}");
246 c31f4e95 Viktor G
					unlink_if_exists("/var/db/captiveportal{$cpzone}.db");
247
					unlink_if_exists("/var/db/captiveportal_usedmacs_{$cpzone}.db");
248
					unlink_if_exists("/var/db/voucher_{$cpzone}_*.db");
249 7cab6335 Renato Botelho
				}
250
			}
251
		}
252
253 1bb9c407 Marcos Mendoza
		$group_config = config_get_path('system/group', []);
254 d3cc158c jim-p
		/* Only touch users if users are set to synchronize from the primary node
255
		 * See https://redmine.pfsense.org/issues/8450
256
		 */
257
		if ($sections['system']['user'] && $sections['system']['group']) {
258
			$g2add = array();
259
			$g2del = array();
260
			$g2del_idx = array();
261
			$g2keep = array();
262
			if (is_array($sections['system']['group'])) {
263 1bb9c407 Marcos Mendoza
				$local_groups = $group_config;
264 d3cc158c jim-p
265
				foreach ($sections['system']['group'] as $group) {
266
					$idx = array_search($group['name'],
267
					    array_column($local_groups, 'name'));
268
269
					if ($idx === false) {
270 f9f395f5 Marcos Mendoza
						// section config group not found in local config
271 d3cc158c jim-p
						$g2add[] = $group;
272 3e0facb2 Marcos Mendoza
					} else if ($group['gid'] < 2000) {
273 f9f395f5 Marcos Mendoza
						// section config group found in local config and is a special group
274 d3cc158c jim-p
						$g2keep[] = $idx;
275
					} else if ($group != $local_groups[$idx]) {
276 f9f395f5 Marcos Mendoza
						// section config group found in local config with different settings
277 d3cc158c jim-p
						$g2add[] = $group;
278
						$g2del[] = $group;
279
						$g2del_idx[] = $idx;
280
					} else {
281 f9f395f5 Marcos Mendoza
						// section config group found in local config and its settings are synced
282 d3cc158c jim-p
						$g2keep[] = $idx;
283
					}
284 79f7bc7f Renato Botelho
				}
285
			}
286 1bb9c407 Marcos Mendoza
			if (is_array($group_config)) {
287
				foreach ($group_config as $idx => $group) {
288 d3cc158c jim-p
					if (array_search($idx, $g2keep) === false &&
289
					    array_search($idx, $g2del_idx) === false) {
290 f9f395f5 Marcos Mendoza
						// local config group not in section config group
291 d3cc158c jim-p
						$g2del[] = $group;
292
						$g2del_idx[] = $idx;
293
					}
294 79f7bc7f Renato Botelho
				}
295
			}
296 d3cc158c jim-p
			unset($sections['system']['group'], $g2keep, $g2del_idx);
297
298
			$u2add = array();
299
			$u2del = array();
300
			$u2del_idx = array();
301
			$u2keep = array();
302 1bb9c407 Marcos Mendoza
			$user_config = config_get_path('system/user', []);
303 d3cc158c jim-p
			if (is_array($sections['system']['user'])) {
304 1bb9c407 Marcos Mendoza
				$local_users = $user_config;
305 d3cc158c jim-p
306
				foreach ($sections['system']['user'] as $user) {
307
					$idx = array_search($user['name'],
308
					    array_column($local_users, 'name'));
309
310
					if ($idx === false) {
311
						$u2add[] = $user;
312 f9ed5d57 James Webb
					} else if (($user['uid'] < 2000) && ($sections['hasync']['adminsync'] != 'on')) {
313 d3cc158c jim-p
						$u2keep[] = $idx;
314
					} else if ($user != $local_users[$idx]) {
315
						$u2add[] = $user;
316
						$u2del[] = $user;
317
						$u2del_idx[] = $idx;
318
					} else {
319
						$u2keep[] = $idx;
320
					}
321 79f7bc7f Renato Botelho
				}
322
			}
323 1bb9c407 Marcos Mendoza
			if (is_array($user_config)) {
324
				foreach ($user_config as $idx => $user) {
325 d3cc158c jim-p
					if (array_search($idx, $u2keep) === false &&
326
					    array_search($idx, $u2del_idx) === false) {
327
						$u2del[] = $user;
328
						$u2del_idx[] = $idx;
329
					}
330 79f7bc7f Renato Botelho
				}
331
			}
332 d3cc158c jim-p
			unset($sections['system']['user'], $u2keep, $u2del_idx);
333 79f7bc7f Renato Botelho
		}
334
335 b8963db6 Renato Botelho
		$voucher = array();
336
		if (is_array($sections['voucher'])) {
337
			/* Save voucher rolls to process after merge */
338
			$voucher = $sections['voucher'];
339
340
			foreach($sections['voucher'] as $zone => $item) {
341
				unset($sections['voucher'][$zone]['roll']);
342 06ef0830 Augustin-FL
				// Note : This code can be safely deleted once #97 fix has been applied and deployed to pfSense stable release.
343
				// Please do not delete this code before
344 63d6bb4f Marcos Mendoza
				if (config_get_path("voucher/{$zone}/vouchersyncdbip") !== null) {
345 b8963db6 Renato Botelho
					$sections['voucher'][$zone]['vouchersyncdbip'] =
346 829322b3 Christian McDonald
					    config_get_path("voucher/{$zone}/vouchersyncdbip");
347 b8963db6 Renato Botelho
				} else {
348
					unset($sections['voucher'][$zone]['vouchersyncdbip']);
349
				}
350 63d6bb4f Marcos Mendoza
				if (config_get_path("voucher/{$zone}/vouchersyncusername") !== null) {
351 b8963db6 Renato Botelho
					$sections['voucher'][$zone]['vouchersyncusername'] =
352 829322b3 Christian McDonald
					    config_get_path("voucher/{$zone}/vouchersyncusername");
353 b8963db6 Renato Botelho
				} else {
354
					unset($sections['voucher'][$zone]['vouchersyncusername']);
355
				}
356 63d6bb4f Marcos Mendoza
				if (config_get_path("voucher/{$zone}/vouchersyncpass") !== null) {
357 b8963db6 Renato Botelho
					$sections['voucher'][$zone]['vouchersyncpass'] =
358 829322b3 Christian McDonald
					    config_get_path("voucher/{$zone}/vouchersyncpass");
359 b8963db6 Renato Botelho
				} else {
360
					unset($sections['voucher'][$zone]['vouchersyncpass']);
361
				}
362 06ef0830 Augustin-FL
				// End note.
363 b8963db6 Renato Botelho
			}
364
		}
365
366 06ef0830 Augustin-FL
		if (is_array($sections['captiveportal'])) {
367
			// Captiveportal : Backward HA settings should remain local.
368
			foreach ($sections['captiveportal'] as $zone => $cp) {
369 63d6bb4f Marcos Mendoza
				if (config_path_enabled("captiveportal/{$zone}", "enablebackwardsync")) {
370 829322b3 Christian McDonald
					$sections['captiveportal'][$zone]['enablebackwardsync'] = config_get_path("captiveportal/{$zone}/enablebackwardsync");
371 06ef0830 Augustin-FL
				} else {
372
					unset($sections['captiveportal'][$zone]['enablebackwardsync']);
373
				}
374 63d6bb4f Marcos Mendoza
				if (config_get_path("captiveportal/{$zone}/backwardsyncip") !== null) {
375 829322b3 Christian McDonald
					$sections['captiveportal'][$zone]['backwardsyncip'] = config_get_path("captiveportal/{$zone}/backwardsyncip");
376 06ef0830 Augustin-FL
				} else {
377
					unset($sections['captiveportal'][$zone]['backwardsyncip']);
378
				}
379 63d6bb4f Marcos Mendoza
				if (config_get_path("captiveportal/{$zone}/backwardsyncuser") !== null) {
380 829322b3 Christian McDonald
					$sections['captiveportal'][$zone]['backwardsyncuser'] = config_get_path("captiveportal/{$zone}/backwardsyncuser");
381 06ef0830 Augustin-FL
				} else {
382
					unset($sections['captiveportal'][$zone]['backwardsyncuser']);
383
				}
384 63d6bb4f Marcos Mendoza
				if (config_get_path("captiveportal/{$zone}/backwardsyncpassword") !== null) {
385 829322b3 Christian McDonald
					$sections['captiveportal'][$zone]['backwardsyncpassword'] = config_get_path("captiveportal/{$zone}/backwardsyncpassword");
386 06ef0830 Augustin-FL
				} else {
387
					unset($sections['captiveportal'][$zone]['vouchersyncpass']);
388
				}
389 b8963db6 Renato Botelho
			}
390 63d6bb4f Marcos Mendoza
			config_set_path('captiveportal', $sections['captiveportal']);
391 06ef0830 Augustin-FL
			unset($sections['captiveportal']);
392 b8963db6 Renato Botelho
		}
393
394 f81e7cc4 Renato Botelho
		$vipbackup = array();
395
		$oldvips = array();
396 9bfd8974 jim-p
		if (array_key_exists('virtualip', $sections)) {
397
			foreach (config_get_path('virtualip/vip', []) as $vip) {
398
				if (empty($vip)) {
399
					continue;
400
				}
401 c14781e3 Renato Botelho
				if ($vip['mode'] == "carp") {
402 f81e7cc4 Renato Botelho
					$key = $vip['interface'] .
403
					    "_vip" . $vip['vhid'];
404
405
					$oldvips[$key]['content'] =
406
					    $vip['password'] .
407
					    $vip['advskew'] .
408
					    $vip['subnet'] .
409
					    $vip['subnet_bits'] .
410
					    $vip['advbase'];
411
					$oldvips[$key]['interface'] =
412
					    $vip['interface'];
413
					$oldvips[$key]['subnet'] =
414
					    $vip['subnet'];
415
				} else if ($vip['mode'] == "ipalias" &&
416
				    (substr($vip['interface'], 0, 4) == '_vip'
417
				    || strstr($vip['interface'], "lo0"))) {
418
					$oldvips[$vip['subnet']]['content'] =
419
					    $vip['interface'] .
420
					    $vip['subnet'] .
421
					    $vip['subnet_bits'];
422
					$oldvips[$vip['subnet']]['interface'] =
423
					    $vip['interface'];
424
					$oldvips[$vip['subnet']]['subnet'] =
425
					    $vip['subnet'];
426
				} else if (($vip['mode'] == "ipalias" ||
427
				    $vip['mode'] == 'proxyarp') &&
428
				    !(substr($vip['interface'], 0, 4) == '_vip')
429
				    || strstr($vip['interface'], "lo0")) {
430 51611440 Ermal
					$vipbackup[] = $vip;
431 c14781e3 Renato Botelho
				}
432 51611440 Ermal
			}
433 19b5c3e7 Ermal
		}
434 f51d4f98 Ermal
435 f81e7cc4 Renato Botelho
		/* For vip section, first keep items sent from the master */
436 63d6bb4f Marcos Mendoza
		config_set_path('', array_merge_recursive_unique(config_get_path(''), $sections));
437 51611440 Ermal
438 a4cd7de1 Christian McDonald
		/* Special handling for Kea HA, skip receiving certain settings from master */
439
		foreach (['kea', 'kea6'] as $kea) {
440
			if (array_path_enabled($old_config, $kea.'/ha', 'tls')) {
441
				config_set_path($kea.'/ha/tls', true);
442
				if ($value = array_get_path($old_config, $kea.'/ha/scertref')) {
443
					config_set_path($kea.'/ha/scertref', $value);
444
				} else {
445
					config_del_path($kea.'/ha/scertref');
446
				}
447
				if (array_path_enabled($old_config, $kea.'/ha', 'mutualtls')) {
448
					config_set_path($kea.'/ha/mutualtls', true);
449
					if ($value = array_get_path($old_config, $kea.'/ha/ccertref')) {
450
						config_set_path($kea.'/ha/ccertref', $value);
451
					} else {
452
						config_del_path($kea.'/ha/ccertref');
453
					}
454
				}
455
			} else {
456
				config_del_path($kea.'/ha/tls');
457
				config_del_path($kea.'/ha/scertref');
458
				config_del_path($kea.'/ha/mutualtls');
459
				config_del_path($kea.'/ha/ccertref');
460
			}
461
462
			if ($value = array_get_path($old_config, $kea.'/ha/localname')) {
463
				config_set_path($kea.'/ha/localname', $value);
464
			} else {
465
				config_del_path($kea.'/ha/localname');
466
			}
467
		}
468
469 b8963db6 Renato Botelho
		/* Remove locally items removed remote */
470
		foreach ($voucher as $zone => $item) {
471
			/* No rolls on master, delete local ones */
472
			if (!is_array($item['roll'])) {
473 7e3ea4a8 Christian McDonald
				config_del_path("voucher/{$zone}/roll");
474 b8963db6 Renato Botelho
			}
475
		}
476
477
		$l_rolls = array();
478 63d6bb4f Marcos Mendoza
		if (is_array(config_get_path('voucher'))) {
479 ac0a027f Christian McDonald
			foreach (config_get_path('voucher', []) as $zone => $item) {
480 b8963db6 Renato Botelho
				if (!is_array($item['roll'])) {
481
					continue;
482
				}
483
				foreach ($item['roll'] as $idx => $roll) {
484
					/* Make it easy to find roll by # */
485
					$l_rolls[$zone][$roll['number']] = $idx;
486
				}
487
			}
488
		}
489
490
		/*
491
		 * Process vouchers sent by primary node and:
492
		 * - Add new items
493
		 * - Update existing items based on 'lastsync' field
494
		 */
495
		foreach ($voucher as $zone => $item) {
496
			if (!is_array($item['roll'])) {
497
				continue;
498
			}
499 63d6bb4f Marcos Mendoza
			config_init_path("voucher/{$zone}");
500
			$l_vouchers = config_get_path("voucher/{$zone}");
501 d35a18fc Christian McDonald
			foreach ($item['roll'] as $roll) {
502 b8963db6 Renato Botelho
				if (!isset($l_rolls[$zone][$roll['number']])) {
503 63d6bb4f Marcos Mendoza
					$l_vouchers['roll'][] = $roll;
504 b8963db6 Renato Botelho
					continue;
505
				}
506
				$l_roll_idx = $l_rolls[$zone][$roll['number']];
507
				$l_roll = $l_vouchers['roll'][$l_roll_idx];
508
				if (!isset($l_roll['lastsync'])) {
509
					$l_roll['lastsync'] = 0;
510
				}
511
512
				if (isset($roll['lastsync']) &&
513
				    $roll['lastsync'] != $l_roll['lastsync']) {
514
					$l_vouchers['roll'][$l_roll_idx] =
515
					    $roll;
516
					unset($l_rolls[$zone][$roll['number']]);
517
				}
518
			}
519 63d6bb4f Marcos Mendoza
			config_set_path("voucher/{$zone}", $l_vouchers);
520 b8963db6 Renato Botelho
		}
521
522
		/*
523
		 * At this point $l_rolls contains only items that are not
524
		 * present on primary node. They must be removed
525
		 */
526
		foreach ($l_rolls as $zone => $item) {
527 d35a18fc Christian McDonald
			foreach ($item as $idx) {
528 7e3ea4a8 Christian McDonald
				config_del_path("voucher/{$zone}/{$idx}");
529 b8963db6 Renato Botelho
			}
530
		}
531
532 f81e7cc4 Renato Botelho
		/*
533
		 * Then add ipalias and proxyarp types already defined
534
		 * on the backup
535
		 */
536
		if (is_array($vipbackup) && !empty($vipbackup)) {
537 9bfd8974 jim-p
			$vips = config_get_path('virtualip/vip', []);
538 f81e7cc4 Renato Botelho
			foreach ($vipbackup as $vip) {
539 9bfd8974 jim-p
				array_unshift($vips, $vip);
540 f81e7cc4 Renato Botelho
			}
541 9bfd8974 jim-p
			config_set_path('virtualip/vip', $vips);
542 962f215d Phil Davis
		}
543 51611440 Ermal
544 f81e7cc4 Renato Botelho
		/* Log what happened */
545 8cb29dac doktornotor
		$mergedkeys = implode(", ", array_merge(array_keys($sections),
546 f81e7cc4 Renato Botelho
		    $syncd_full_sections));
547
		write_config(sprintf(gettext(
548
		    "Merged in config (%s sections) from XMLRPC client."),
549
		    $mergedkeys));
550
551
		/*
552
		 * The real work on handling the vips specially
553 51b0b50b jim-p
		 * This is a copy of interfaces_vips_configure with addition of
554 f81e7cc4 Renato Botelho
		 * not reloading existing/not changed carps
555
		 */
556 23fcdccc Viktor G
		$force_filterconfigure = false;
557 f81e7cc4 Renato Botelho
		if (isset($sections['virtualip']) &&
558 63d6bb4f Marcos Mendoza
		    is_array(config_get_path('virtualip/vip'))) {
559 f81e7cc4 Renato Botelho
			$carp_setuped = false;
560
			$anyproxyarp = false;
561
562 ac0a027f Christian McDonald
			foreach (config_get_path('virtualip/vip', []) as $vip) {
563 f81e7cc4 Renato Botelho
				$key = "{$vip['interface']}_vip{$vip['vhid']}";
564
565
				if ($vip['mode'] == "carp" &&
566
				    isset($oldvips[$key])) {
567
					if ($oldvips[$key]['content'] ==
568
					    $vip['password'] .
569
					    $vip['advskew'] .
570
					    $vip['subnet'] .
571
					    $vip['subnet_bits'] .
572
					    $vip['advbase'] &&
573
					    does_vip_exist($vip)) {
574
						unset($oldvips[$key]);
575
						/*
576
						 * Skip reconfiguring this vips
577
						 * since nothing has changed.
578
						 */
579
						continue;
580 19ed1624 Ermal
					}
581 5fda51cd jim-p
582 f81e7cc4 Renato Botelho
				} elseif ($vip['mode'] == "ipalias" &&
583 5fda51cd jim-p
				    (substr($vip['interface'], 0, 4) == '_vip'
584
				    || strstr($vip['interface'], "lo0")) &&
585 f81e7cc4 Renato Botelho
				    isset($oldvips[$vip['subnet']])) {
586
					$key = $vip['subnet'];
587
					if ($oldvips[$key]['content'] ==
588
					    $vip['interface'] .
589
					    $vip['subnet'] .
590
					    $vip['subnet_bits'] &&
591
					    does_vip_exist($vip)) {
592
						unset($oldvips[$key]);
593
						/*
594
						 * Skip reconfiguring this vips
595
						 * since nothing has changed.
596
						 */
597
						continue;
598 2708a5cf Ermal
					}
599 f81e7cc4 Renato Botelho
					unset($oldvips[$key]);
600 2708a5cf Ermal
				}
601 51611440 Ermal
602 f81e7cc4 Renato Botelho
				switch ($vip['mode']) {
603 962f215d Phil Davis
				case "proxyarp":
604
					$anyproxyarp = true;
605
					break;
606
				case "ipalias":
607
					interface_ipalias_configure($vip);
608
					break;
609
				case "carp":
610 f81e7cc4 Renato Botelho
					$carp_setuped = true;
611 3c15b353 Viktor G
					if (does_vip_exist($vip) && isset($oldvips[$key]['vhid']) &&
612
					    ($oldvips[$key]['vhid'] ^ $vip['vhid'])) {
613
						/* properly remove the old VHID
614
						 * see https://redmine.pfsense.org/issues/12202 */
615
						$realif = get_real_interface($vip['interface']);
616
						mwexec("/sbin/ifconfig {$realif} " .
617
							escapeshellarg($vip['subnet']) . " -alias");
618
						$ipalias_reload = true;
619
					} else {
620
						$ipalias_reload = false;
621
					}
622
					interface_carp_configure($vip, false, $ipalias_reload);
623 962f215d Phil Davis
					break;
624 f81e7cc4 Renato Botelho
				}
625 23fcdccc Viktor G
				$force_filterconfigure = true;
626 51611440 Ermal
			}
627 f81e7cc4 Renato Botelho
628
			/* Cleanup remaining old carps */
629
			foreach ($oldvips as $oldvipar) {
630
				$oldvipif = get_real_interface(
631
				    $oldvipar['interface']);
632
633
				if (empty($oldvipif)) {
634
					continue;
635
				}
636
637 e7cac368 Viktor G
				/* do not remove VIP if the IP address remains the same */
638 ac0a027f Christian McDonald
				foreach (config_get_path('virtualip/vip', []) as $vip) {
639 e7cac368 Viktor G
					if ($vip['subnet'] == $oldvipar['subnet']) {
640
						continue 2;
641
					}
642
				}
643
644 962f215d Phil Davis
				if (is_ipaddrv6($oldvipar['subnet'])) {
645 f81e7cc4 Renato Botelho
					 mwexec("/sbin/ifconfig " .
646
					     escapeshellarg($oldvipif) .
647
					     " inet6 " .
648
					     escapeshellarg($oldvipar['subnet']) .
649
					     " delete");
650 962f215d Phil Davis
				} else {
651 f81e7cc4 Renato Botelho
					pfSense_interface_deladdress($oldvipif,
652
					    $oldvipar['subnet']);
653 962f215d Phil Davis
				}
654 e3cffd6c Ermal LUÇI
			}
655 f81e7cc4 Renato Botelho
			if ($carp_setuped == true) {
656
				interfaces_sync_setup();
657
			}
658
			if ($anyproxyarp == true) {
659
				interface_proxyarp_configure();
660
			}
661 51611440 Ermal
		}
662 f81e7cc4 Renato Botelho
663 79f7bc7f Renato Botelho
		local_sync_accounts($u2add, $u2del, $g2add, $g2del);
664 23fcdccc Viktor G
		$this->filter_configure(false, $force_filterconfigure);
665
		unset($old_config);
666 79f7bc7f Renato Botelho
667 f81e7cc4 Renato Botelho
		return true;
668 962f215d Phil Davis
	}
669 d026178f Renato Botelho
670 f81e7cc4 Renato Botelho
	/**
671
	 * Merge items into installedpackages config section
672
	 *
673
	 * @param array $section
674
	 *
675
	 * @return bool
676
	 */
677 4f26f187 Viktor G
	public function merge_installedpackages_section($section, $timeout) {
678
		ini_set('default_socket_timeout', $timeout);
679 dc5f639f PiBa-NL
		$this->auth();
680 d026178f Renato Botelho
681 f81e7cc4 Renato Botelho
		if ($this->loop_detected) {
682
			log_error("Disallowing CARP sync loop");
683
			return true;
684
		}
685 82ae5cfc Scott Ullrich
686 63d6bb4f Marcos Mendoza
		config_set_path('installedpackages', array_merge(
687
		    config_get_path('installedpackages'), $section));
688 8cb29dac doktornotor
		$mergedkeys = implode(", ", array_keys($section));
689 f81e7cc4 Renato Botelho
		write_config(sprintf(gettext(
690
		    "Merged in config (%s sections) from XMLRPC client."),
691
		    $mergedkeys));
692 137f46d8 Ermal
693 f81e7cc4 Renato Botelho
		return true;
694 fb0eb20b Ermal
	}
695 c87f4b70 Ermal
696 f81e7cc4 Renato Botelho
	/**
697
	 * Merge items into config
698
	 *
699
	 * @param array $section
700
	 *
701
	 * @return bool
702
	 */
703 4f26f187 Viktor G
	public function merge_config_section($section, $timeout) {
704
		ini_set('default_socket_timeout', $timeout);
705 dc5f639f PiBa-NL
		$this->auth();
706 137f46d8 Ermal
707 f81e7cc4 Renato Botelho
		if ($this->loop_detected) {
708
			log_error("Disallowing CARP sync loop");
709
			return true;
710
		}
711 dc1cd85d Scott Ullrich
712 63d6bb4f Marcos Mendoza
		config_set_path('', $this->array_overlay(config_get_path(''), $section));
713 8cb29dac doktornotor
		$mergedkeys = implode(", ", array_keys($section));
714 f81e7cc4 Renato Botelho
		write_config(sprintf(gettext(
715
		    "Merged in config (%s sections) from XMLRPC client."),
716
		    $mergedkeys));
717 c87f4b70 Ermal
718 f81e7cc4 Renato Botelho
		return true;
719 fb0eb20b Ermal
	}
720 c87f4b70 Ermal
721 f81e7cc4 Renato Botelho
	/**
722
	 * Wrapper for filter_configure()
723
	 *
724
	 * @return bool
725 57b5da70 jim-p
	 */
726 23fcdccc Viktor G
	private function filter_configure($reset_accounts = true, $force = false) {
727 63d6bb4f Marcos Mendoza
		global $g, $old_config;
728 f81e7cc4 Renato Botelho
729
		filter_configure();
730
		system_routing_configure();
731
		setup_gateways_monitor();
732 23fcdccc Viktor G
733
		/* do not restart unchanged services on XMLRPC sync,
734
		 * see https://redmine.pfsense.org/issues/11082 
735
		 */
736 63d6bb4f Marcos Mendoza
		if (is_array(config_get_path('openvpn')) || is_array($old_config['openvpn'])) {
737 23fcdccc Viktor G
			foreach (array("server", "client") as $type) {
738
				$remove_id = array();
739 63d6bb4f Marcos Mendoza
				if (is_array(array_get_path($old_config, "openvpn/openvpn-{$type}"))) {
740 ac0a027f Christian McDonald
					foreach ($old_config['openvpn']["openvpn-{$type}"] as $old_settings) {
741 23fcdccc Viktor G
						$remove_id[] = $old_settings['vpnid'];
742
					}
743
				}
744 63d6bb4f Marcos Mendoza
				if (!is_array(config_get_path("openvpn/openvpn-{$type}"))) {
745 23fcdccc Viktor G
					continue;
746
				}
747 ac0a027f Christian McDonald
				foreach (config_get_path("openvpn/openvpn-{$type}", []) as $settings) {
748 23fcdccc Viktor G
					$new_instance = true;
749
					if (in_array($settings['vpnid'], $remove_id)) {
750
						$remove_id = array_diff($remove_id, array($settings['vpnid']));
751
					}
752 63d6bb4f Marcos Mendoza
					if (is_array(array_get_path($old_config, "openvpn/openvpn-{$type}"))) {
753 ac0a027f Christian McDonald
						foreach ($old_config['openvpn']["openvpn-{$type}"] as $old_settings) {
754 23fcdccc Viktor G
							if ($settings['vpnid'] == $old_settings['vpnid']) {
755
								$new_instance = false;
756
								if (($settings != $old_settings) || $force) {
757
									/* restart changed openvpn instance */
758
									openvpn_resync($type, $settings);
759
									break;
760
								}
761
							}
762
						}
763
					}
764
					if ($new_instance) {
765
						/* start new openvpn instance */
766
						openvpn_resync($type, $settings);
767
					}
768
				}
769
				if (!empty($remove_id)) {
770
					foreach ($remove_id as $id) {
771
						/* stop/delete removed openvpn instances */
772
						openvpn_delete($type, array('vpnid' => $id));
773
					}
774
				}
775
			}
776
			/* no service restart required */
777
			openvpn_resync_csc_all();
778
		}
779 f81e7cc4 Renato Botelho
780 6ae26227 Viktor G
		/* run ipsec_configure() on any IPsec change, see https://redmine.pfsense.org/issues/12075 */
781 63d6bb4f Marcos Mendoza
		if (((is_array(config_get_path('ipsec')) || is_array($old_config['ipsec'])) &&
782
		    (config_get_path('ipsec') != $old_config['ipsec'])) ||
783 6ae26227 Viktor G
		    $force) {
784
			ipsec_configure();
785
		}
786
787 f81e7cc4 Renato Botelho
		/*
788
		 * The DNS Resolver and the DNS Forwarder may both be active so
789
		 * long as * they are running on different ports.
790
		 * See ticket #5882
791
		 */
792 63d6bb4f Marcos Mendoza
		if (((is_array(config_get_path('dnsmasq')) || is_array($old_config['dnsmasq'])) &&
793
		    (config_get_path('dnsmasq') != $old_config['dnsmasq'])) ||
794 23fcdccc Viktor G
		    $force) {
795 63d6bb4f Marcos Mendoza
			if (config_path_enabled('dnsmasq')) {
796 23fcdccc Viktor G
				/* Configure dnsmasq but tell it NOT to restart DHCP */
797
				services_dnsmasq_configure(false);
798
			} else {
799
				/* kill any running dnsmasq instance */
800
				if (isvalidpid("{$g['varrun_path']}/dnsmasq.pid")) {
801
					sigkillbypid("{$g['varrun_path']}/dnsmasq.pid",
802
					    "TERM");
803
				}
804 f81e7cc4 Renato Botelho
			}
805 57b5da70 jim-p
		}
806 63d6bb4f Marcos Mendoza
		if (((is_array(config_get_path('unbound')) || is_array($old_config['unbound'])) &&
807
		    (config_get_path('unbound') != $old_config['unbound'])) ||
808 23fcdccc Viktor G
		    $force) {
809 63d6bb4f Marcos Mendoza
			if (config_path_enabled('unbound')) {
810 23fcdccc Viktor G
				/* Configure unbound but tell it NOT to restart DHCP */
811
				services_unbound_configure(false);
812
			} else {
813
				/* kill any running Unbound instance */
814
				if (isvalidpid("{$g['varrun_path']}/unbound.pid")) {
815
					sigkillbypid("{$g['varrun_path']}/unbound.pid",
816
					    "TERM");
817
				}
818 f81e7cc4 Renato Botelho
			}
819 57b5da70 jim-p
		}
820 137f46d8 Ermal
821 f81e7cc4 Renato Botelho
		/*
822
		 * Call this separately since the above are manually set to
823
		 * skip the DHCP restart they normally perform.
824
		 * This avoids restarting dhcpd twice as described on
825
		 * ticket #3797
826
		 */
827 a4cd7de1 Christian McDonald
		$called = [];
828
		foreach ([
829
			'dhcpd'			=> 'services_dhcpd_configure',
830
			'dhcpdv6'		=> 'services_dhcpd_configure',
831
			'kea'			=> 'services_dhcpd_configure',
832
			'kea6'			=> 'services_dhcpd_configure',
833
			'dhcrelay'		=> 'services_dhcrelay_configure',
834
			'dhcrelay6'		=> 'services_dhcrelay6_configure',
835
			'captiveportal'	=> 'captiveportal_configure',
836
			'voucher'		=> 'voucher_configure'
837
		] as $path => $fn) {
838
			if (!array_key_exists($fn, $called)) {
839
				if (((is_array(config_get_path($path)) || is_array($old_config[$path])) &&
840
			        (config_get_path($path) !== array_get_path($old_config, $path))) || $force) {
841
					if (is_callable($fn)) {
842
						$fn();
843
					}
844
					$called[$fn] = true;
845
				}
846
			}
847 30169caa Viktor G
		}
848
849 79f7bc7f Renato Botelho
		if ($reset_accounts) {
850
			local_reset_accounts();
851
		}
852 c87f4b70 Ermal
853 f81e7cc4 Renato Botelho
		return true;
854 3dd2a278 Scott Ullrich
	}
855 137f46d8 Ermal
856 24600471 Augustin-FL
	/**
857
	 * Wrapper for captiveportal connected users and
858
	 * active/expired vouchers synchronization
859
	 *
860
	 * @param array $arguments
861
	 *
862 d900b9d4 Marcos Mendoza
	 * @return array|bool|null
863 24600471 Augustin-FL
	 */
864 4f26f187 Viktor G
	public function captive_portal_sync($arguments, $timeout) {
865
		ini_set('default_socket_timeout', $timeout);
866 24600471 Augustin-FL
		$this->auth();
867
		// Note : no protection against CARP loop is done here, and this is in purpose.
868
		// This function is used for bi-directionnal sync, which is precisely what CARP loop protection is supposed to prevent.
869
		// CARP loop has to be managed within functions using captive_portal_sync()
870 63d6bb4f Marcos Mendoza
		global $g, $cpzone;
871 24600471 Augustin-FL
872 63d6bb4f Marcos Mendoza
		if (empty($arguments['op']) || empty($arguments['zone']) || empty(config_get_path("captiveportal/{$arguments['zone']}"))) {
873 24600471 Augustin-FL
			return false;
874
		}
875
		$cpzone = $arguments['zone'];
876
877
		if ($arguments['op'] === 'get_databases') {
878 8de9ebba Christian McDonald
			$active_vouchers = [];
879
			$expired_vouchers = [];
880
			$usedmacs = [];
881 24600471 Augustin-FL
882 63d6bb4f Marcos Mendoza
			foreach(config_get_path("voucher/{$cpzone}/roll", []) as $roll) {
883
				$expired_vouchers[$roll['number']] = base64_encode(voucher_read_used_db($roll['number']));
884
				$active_vouchers[$roll['number']] = voucher_read_active_db($roll['number']);
885 24600471 Augustin-FL
			}
886 63d6bb4f Marcos Mendoza
			if (!empty(config_get_path("captiveportal/{$cpzone}/freelogins_count")) &&
887
			    !empty(config_get_path("captiveportal/{$cpzone}/freelogins_resettimeout"))) {
888 a81a6edc Viktor G
				$usedmacs = captiveportal_read_usedmacs_db();
889
			}
890 24600471 Augustin-FL
			// base64 is here for safety reasons, as we don't fully control
891
			// the content of these arrays.
892
			$returndata = array('connected_users' => base64_encode(serialize(captiveportal_read_db())),
893
			'active_vouchers' => base64_encode(serialize($active_vouchers)),
894 a81a6edc Viktor G
			'expired_vouchers' => base64_encode(serialize($expired_vouchers)),
895
			'usedmacs' => base64_encode(serialize($usedmacs)));
896 24600471 Augustin-FL
897
			return $returndata;
898
		} elseif ($arguments['op'] === 'connect_user') {
899 82e22457 Marcos Mendoza
			$user = unserialize_data(base64_decode($arguments['user']), []);
900 24600471 Augustin-FL
			$user['attributes']['allow_time'] = $user['allow_time'];
901
902
			// pipeno might be different between primary and secondary
903
			$pipeno = captiveportal_get_next_dn_ruleno('auth');
904
			return portal_allow($user['clientip'], $user['clientmac'], $user['username'], $user['password'], null,
905
			    $user['attributes'], $pipeno, $user['authmethod'], $user['context'], $user['sessionid']);
906 4a778ba9 Augustin-FL
		} elseif ($arguments['op'] === 'disconnect_user') {
907 82e22457 Marcos Mendoza
			$session = unserialize_data(base64_decode($arguments['session']), []);
908 4a778ba9 Augustin-FL
			/* read database again, as pipeno might be different between primary & secondary */
909
			$sessionid = SQLite3::escapeString($session['sessionid']);
910
			$local_dbentry = captiveportal_read_db("WHERE sessionid = '{$sessionid}'");
911
912
			if (!empty($local_dbentry) && count($local_dbentry) == 1) {
913
				return captiveportal_disconnect($local_dbentry[0], $session['term_cause'], $session['stop_time'], true);
914
			} else {
915
				return false;
916
			}
917
		} elseif ($arguments['op'] === 'remove_entries') {
918 82e22457 Marcos Mendoza
			$entries = unserialize_data(base64_decode($arguments['entries']), []);
919 4a778ba9 Augustin-FL
920
			return captiveportal_remove_entries($entries, true);
921 78784180 Augustin-FL
		} elseif ($arguments['op'] === 'disconnect_all') {
922 82e22457 Marcos Mendoza
			$arguments = unserialize_data(base64_decode($arguments['arguments']), []);
923 78784180 Augustin-FL
924
			return captiveportal_disconnect_all($arguments['term_cause'], $arguments['logout_reason'], true);
925 318e3f81 Augustin-FL
		} elseif ($arguments['op'] === 'write_vouchers') {
926 82e22457 Marcos Mendoza
			$arguments = unserialize_data(base64_decode($arguments['arguments']), []);
927 318e3f81 Augustin-FL
928
			if (is_array($arguments['active_and_used_vouchers_bitmasks'])) {
929
				foreach ($arguments['active_and_used_vouchers_bitmasks'] as $roll => $used) {
930
					if (is_array($used)) {
931
						foreach ($used as $u) {
932
							voucher_write_used_db($roll, base64_encode($u));
933
						}
934
					} else {
935
						voucher_write_used_db($roll, base64_encode($used));
936
					}
937
				}
938
			}
939
			foreach ($arguments['active_vouchers'] as $roll => $active_vouchers) {
940
				voucher_write_active_db($roll, $active_vouchers);
941
			}
942
			return true;
943 a81a6edc Viktor G
		} elseif ($arguments['op'] === 'write_usedmacs') {
944 82e22457 Marcos Mendoza
			$arguments = unserialize_data(base64_decode($arguments['arguments']), []);
945 a81a6edc Viktor G
946
			captiveportal_write_usedmacs_db($arguments['usedmacs']); 
947
			return true;
948 24600471 Augustin-FL
		}
949
	}
950
951 f81e7cc4 Renato Botelho
	/**
952
	 * Wrapper for configuring CARP interfaces
953
	 *
954
	 * @return bool
955
	 */
956 dc5f639f PiBa-NL
	public function interfaces_carp_configure() {
957
		$this->auth();
958 efe7562e Scott Ullrich
959 f81e7cc4 Renato Botelho
		if ($this->loop_detected) {
960
			log_error("Disallowing CARP sync loop");
961
			return true;
962
		}
963 0567899d Ermal
964 f81e7cc4 Renato Botelho
		interfaces_vips_configure();
965 e501de37 Ermal
966 f81e7cc4 Renato Botelho
		return true;
967
	}
968 e501de37 Ermal
969 f81e7cc4 Renato Botelho
	/**
970
	 * Wrapper for rc.reboot
971
	 *
972
	 * @return bool
973
	 */
974 dc5f639f PiBa-NL
	public function reboot() {
975
		$this->auth();
976 e501de37 Ermal
977 f81e7cc4 Renato Botelho
		mwexec_bg("/etc/rc.reboot");
978 137f46d8 Ermal
979 f81e7cc4 Renato Botelho
		return true;
980 3dd2a278 Scott Ullrich
	}
981 d9064267 Colin Smith
}
982
983 f3f98e97 Phil Davis
// run script until its done and can 'unlock' the xmlrpc.lock, this prevents hanging php-fpm / webgui
984 179377b0 robjarsen
ignore_user_abort(true);
985 8239af2d PiBa-NL
set_time_limit(0);
986
987 67d78c87 Ermal
$xmlrpclockkey = lock('xmlrpc', LOCK_EX);
988
989 f81e7cc4 Renato Botelho
XML_RPC2_Backend::setBackend('php');
990
$HTTP_RAW_POST_DATA = file_get_contents('php://input');
991
992
$options = array(
993
	'prefix' => 'pfsense.',
994
	'encoding' => 'utf-8',
995 4f78ae1d Renato Botelho
	'autoDocument' => false,
996 50d49018 Colin Smith
);
997 b298dd06 Scott Ullrich
998 f81e7cc4 Renato Botelho
$server = XML_RPC2_Server::create(new pfsense_xmlrpc_server(), $options);
999
$server->handleCall();
1000 67d78c87 Ermal
1001 f81e7cc4 Renato Botelho
unlock($xmlrpclockkey);
1002 0b581a8a Scott Ullrich
1003 de63649b Rafael Lucas
?>