Project

General

Profile

Download (18.8 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
 * Copyright (c) 2014-2019 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 7cab6335 Renato Botelho
require_once("captiveportal.inc");
39 c81ef6e2 Phil Davis
require_once("shaper.inc");
40 f81e7cc4 Renato Botelho
require_once("XML/RPC2/Server.php");
41 50d49018 Colin Smith
42 f81e7cc4 Renato Botelho
class pfsense_xmlrpc_server {
43 c87f4b70 Ermal
44 f81e7cc4 Renato Botelho
	private $loop_detected = false;
45
	private $remote_addr;
46 c87f4b70 Ermal
47 dc5f639f PiBa-NL
	private function auth() {
48 f81e7cc4 Renato Botelho
		global $config;
49 dc5f639f PiBa-NL
		$username = $_SERVER['PHP_AUTH_USER'];
50
		$password = $_SERVER['PHP_AUTH_PW'];
51 8da3de34 Colin Smith
52 fb1234ab Renato Botelho
		$login_ok = false;
53 f81e7cc4 Renato Botelho
		if (!empty($username) && !empty($password)) {
54
			$attributes = array();
55
			$authcfg = auth_get_authserver(
56
			    $config['system']['webgui']['authmode']);
57 c3638879 Scott Ullrich
58 f81e7cc4 Renato Botelho
			if (authenticate_user($username, $password,
59
			    $authcfg, $attributes) ||
60
			    authenticate_user($username, $password)) {
61 fb1234ab Renato Botelho
				$login_ok = true;
62 f81e7cc4 Renato Botelho
			}
63
		}
64 3dd2a278 Scott Ullrich
65 fb1234ab Renato Botelho
		if (!$login_ok) {
66 6e0d4751 jim-p
			log_auth(sprintf(gettext("webConfigurator authentication error for user '%1\$s' from: %2\$s"),
67
			    $username,
68
			    $this->remote_addr));
69 137f46d8 Ermal
70 fb1234ab Renato Botelho
			require_once("XML/RPC2/Exception.php");
71
			throw new XML_RPC2_FaultException(gettext(
72
			    'Authentication failed: Invalid username or password'),
73
			    -1);
74
		}
75
76
		$user_entry = getUserEntry($username);
77
		/*
78
		 * admin (uid = 0) is allowed
79
		 * or regular user with necessary privilege
80
		 */
81
		if (isset($user_entry['uid']) && $user_entry['uid'] != '0' &&
82
		    !userHasPrivilege($user_entry, 'system-xmlrpc-ha-sync')) {
83
			log_auth("webConfigurator authentication error for '" .
84
			    $username . "' from " . $this->remote_addr .
85
			    " not enough privileges");
86
87
			require_once("XML/RPC2/Exception.php");
88
			throw new XML_RPC2_FaultException(gettext(
89
			    'Authentication failed: not enough privileges'),
90
			    -2);
91
		}
92
93
		return;
94 3dd2a278 Scott Ullrich
	}
95 f81e7cc4 Renato Botelho
96
	private function array_overlay($a1, $a2) {
97
		foreach ($a1 as $k => $v) {
98
			if (!array_key_exists($k, $a2)) {
99
				continue;
100
			}
101
			if (is_array($v) && is_array($a2[$k])) {
102
				$a1[$k] = $this->array_overlay($v, $a2[$k]);
103
			} else {
104
				$a1[$k] = $a2[$k];
105
			}
106
		}
107
108
		return $a1;
109 962f215d Phil Davis
	}
110 c3638879 Scott Ullrich
111 f81e7cc4 Renato Botelho
	public function __construct() {
112
		global $config;
113 c3638879 Scott Ullrich
114 f82f991c Renato Botelho
		$this->remote_addr = $_SERVER['REMOTE_ADDR'];
115 137f46d8 Ermal
116 f81e7cc4 Renato Botelho
		/* grab sync to ip if enabled */
117
		if (isset($config['hasync']['synchronizetoip']) &&
118 8d44b2cb PiBa-NL
		    $config['hasync']['synchronizetoip'] == $this->remote_addr) {
119 f81e7cc4 Renato Botelho
			$this->loop_detected = true;
120
		}
121 3dd2a278 Scott Ullrich
	}
122 137f46d8 Ermal
123 f81e7cc4 Renato Botelho
	/**
124
	 * Get host version information
125
	 *
126
	 * @return array
127
	 */
128 dc5f639f PiBa-NL
	public function host_firmware_version($dummy = 1) {
129
		$this->auth();
130 f81e7cc4 Renato Botelho
		return host_firmware_version();
131
	}
132 21dc3a7d Colin Smith
133 f81e7cc4 Renato Botelho
	/**
134
	 * Executes a PHP block of code
135
	 *
136
	 * @param string $code
137
	 *
138
	 * @return bool
139
	 */
140 dc5f639f PiBa-NL
	public function exec_php($code) {
141
		$this->auth();
142 137f46d8 Ermal
143 f81e7cc4 Renato Botelho
		eval($code);
144
		if ($toreturn) {
145
			return $toreturn;
146
		}
147 c87f4b70 Ermal
148 f81e7cc4 Renato Botelho
		return true;
149 3dd2a278 Scott Ullrich
	}
150 137f46d8 Ermal
151 f81e7cc4 Renato Botelho
	/**
152
	 * Executes shell commands
153
	 *
154
	 * @param string $code
155
	 *
156
	 * @return bool
157
	 */
158 dc5f639f PiBa-NL
	public function exec_shell($code) {
159
		$this->auth();
160 50d49018 Colin Smith
161 f81e7cc4 Renato Botelho
		mwexec($code);
162
		return true;
163
	}
164 21dc3a7d Colin Smith
165 f81e7cc4 Renato Botelho
	/**
166
	 * Backup chosen config sections
167
	 *
168
	 * @param array $section
169
	 *
170
	 * @return array
171
	 */
172 dc5f639f PiBa-NL
	public function backup_config_section($section) {
173
		$this->auth();
174 137f46d8 Ermal
175 f81e7cc4 Renato Botelho
		global $config;
176 d026178f Renato Botelho
177 f81e7cc4 Renato Botelho
		return array_intersect_key($config, array_flip($section));
178 fb0eb20b Ermal
	}
179 c87f4b70 Ermal
180 f81e7cc4 Renato Botelho
	/**
181
	 * Restore defined config section into local config
182
	 *
183
	 * @param array $sections
184
	 *
185
	 * @return bool
186
	 */
187 dc5f639f PiBa-NL
	public function restore_config_section($sections) {
188
		$this->auth();
189 f81e7cc4 Renato Botelho
190 7cab6335 Renato Botelho
		global $config, $cpzone, $cpzoneid;
191 1b99e1e5 jim-p
192 f81e7cc4 Renato Botelho
		$old_config = $config;
193
		$old_ipsec_enabled = ipsec_enabled();
194
195
		if ($this->loop_detected) {
196
			log_error("Disallowing CARP sync loop");
197
			return true;
198
		}
199
200
		/*
201
		 * Some sections should just be copied and not merged or we end
202
		 * up unable to sync the deletion of the last item in a section
203
		 */
204
		$sync_full_sections = array(
205
			'aliases',
206
			'ca',
207
			'cert',
208
			'crl',
209
			'dhcpd',
210
			'dhcpv6',
211
			'dnsmasq',
212
			'filter',
213
			'ipsec',
214
			'nat',
215
			'openvpn',
216
			'schedules',
217
			'unbound',
218
			'wol',
219
		);
220
221
		$syncd_full_sections = array();
222
223
		foreach ($sync_full_sections as $section) {
224
			if (!isset($sections[$section])) {
225
				continue;
226
			}
227
228
			$config[$section] = $sections[$section];
229
			unset($sections[$section]);
230
			$syncd_full_sections[] = $section;
231 1b99e1e5 jim-p
		}
232
233 7cab6335 Renato Botelho
		/* Create a list of CP zones to be deleted locally */
234
		$cp_to_del = array();
235
		if (is_array($config['captiveportal'])) {
236
			if (is_array($sections['captiveportal'])) {
237
				$remote_cp = $sections['captiveportal'];
238
			} else {
239
				$remote_cp = array();
240
			}
241
			foreach ($config['captiveportal'] as $zone => $item) {
242
				if (!isset($remote_cp[$zone])) {
243
					$cp_to_del[] = $zone;
244
				}
245
			}
246
			unset($remote_cp);
247
		}
248
249 d3cc158c jim-p
		/* Only touch users if users are set to synchronize from the primary node
250
		 * See https://redmine.pfsense.org/issues/8450
251
		 */
252
		if ($sections['system']['user'] && $sections['system']['group']) {
253
			$g2add = array();
254
			$g2del = array();
255
			$g2del_idx = array();
256
			$g2keep = array();
257
			if (is_array($sections['system']['group'])) {
258
				$local_groups = isset($config['system']['group'])
259
				    ? $config['system']['group']
260
				    : array();
261
262
				foreach ($sections['system']['group'] as $group) {
263
					$idx = array_search($group['name'],
264
					    array_column($local_groups, 'name'));
265
266
					if ($idx === false) {
267
						$g2add[] = $group;
268
					} else if ($group['gid'] < 1999) {
269
						$g2keep[] = $idx;
270
					} else if ($group != $local_groups[$idx]) {
271
						$g2add[] = $group;
272
						$g2del[] = $group;
273
						$g2del_idx[] = $idx;
274
					} else {
275
						$g2keep[] = $idx;
276
					}
277 79f7bc7f Renato Botelho
				}
278
			}
279 d3cc158c jim-p
			if (is_array($config['system']['group'])) {
280
				foreach ($config['system']['group'] as $idx => $group) {
281
					if (array_search($idx, $g2keep) === false &&
282
					    array_search($idx, $g2del_idx) === false) {
283
						$g2del[] = $group;
284
						$g2del_idx[] = $idx;
285
					}
286 79f7bc7f Renato Botelho
				}
287
			}
288 d3cc158c jim-p
			unset($sections['system']['group'], $g2keep, $g2del_idx);
289
290
			$u2add = array();
291
			$u2del = array();
292
			$u2del_idx = array();
293
			$u2keep = array();
294
			if (is_array($sections['system']['user'])) {
295
				$local_users = isset($config['system']['user'])
296
				    ? $config['system']['user']
297
				    : array();
298
299
				foreach ($sections['system']['user'] as $user) {
300
					$idx = array_search($user['name'],
301
					    array_column($local_users, 'name'));
302
303
					if ($idx === false) {
304
						$u2add[] = $user;
305
					} else if ($user['uid'] < 2000) {
306
						$u2keep[] = $idx;
307
					} else if ($user != $local_users[$idx]) {
308
						$u2add[] = $user;
309
						$u2del[] = $user;
310
						$u2del_idx[] = $idx;
311
					} else {
312
						$u2keep[] = $idx;
313
					}
314 79f7bc7f Renato Botelho
				}
315
			}
316 d3cc158c jim-p
			if (is_array($config['system']['user'])) {
317
				foreach ($config['system']['user'] as $idx => $user) {
318
					if (array_search($idx, $u2keep) === false &&
319
					    array_search($idx, $u2del_idx) === false) {
320
						$u2del[] = $user;
321
						$u2del_idx[] = $idx;
322
					}
323 79f7bc7f Renato Botelho
				}
324
			}
325 d3cc158c jim-p
			unset($sections['system']['user'], $u2keep, $u2del_idx);
326 79f7bc7f Renato Botelho
		}
327
328 b8963db6 Renato Botelho
		$voucher = array();
329
		if (is_array($sections['voucher'])) {
330
			/* Save voucher rolls to process after merge */
331
			$voucher = $sections['voucher'];
332
333
			foreach($sections['voucher'] as $zone => $item) {
334
				unset($sections['voucher'][$zone]['roll']);
335
				if (isset($config['voucher'][$zone]['vouchersyncdbip'])) {
336
					$sections['voucher'][$zone]['vouchersyncdbip'] =
337
					    $config['voucher'][$zone]['vouchersyncdbip'];
338
				} else {
339
					unset($sections['voucher'][$zone]['vouchersyncdbip']);
340
				}
341
				if (isset($config['voucher'][$zone]['vouchersyncport'])) {
342
					$sections['voucher'][$zone]['vouchersyncport'] =
343
					    $config['voucher'][$zone]['vouchersyncport'];
344
				} else {
345
					unset($sections['voucher'][$zone]['vouchersyncport']);
346
				}
347
				if (isset($config['voucher'][$zone]['vouchersyncusername'])) {
348
					$sections['voucher'][$zone]['vouchersyncusername'] =
349
					    $config['voucher'][$zone]['vouchersyncusername'];
350
				} else {
351
					unset($sections['voucher'][$zone]['vouchersyncusername']);
352
				}
353
				if (isset($config['voucher'][$zone]['vouchersyncpass'])) {
354
					$sections['voucher'][$zone]['vouchersyncpass'] =
355
					    $config['voucher'][$zone]['vouchersyncpass'];
356
				} else {
357
					unset($sections['voucher'][$zone]['vouchersyncpass']);
358
				}
359
			}
360
		}
361
362 f81e7cc4 Renato Botelho
		$vipbackup = array();
363
		$oldvips = array();
364
		if (isset($sections['virtualip']) &&
365
		    is_array($config['virtualip']['vip'])) {
366
			foreach ($config['virtualip']['vip'] as $vip) {
367 c14781e3 Renato Botelho
				if ($vip['mode'] == "carp") {
368 f81e7cc4 Renato Botelho
					$key = $vip['interface'] .
369
					    "_vip" . $vip['vhid'];
370
371
					$oldvips[$key]['content'] =
372
					    $vip['password'] .
373
					    $vip['advskew'] .
374
					    $vip['subnet'] .
375
					    $vip['subnet_bits'] .
376
					    $vip['advbase'];
377
					$oldvips[$key]['interface'] =
378
					    $vip['interface'];
379
					$oldvips[$key]['subnet'] =
380
					    $vip['subnet'];
381
				} else if ($vip['mode'] == "ipalias" &&
382
				    (substr($vip['interface'], 0, 4) == '_vip'
383
				    || strstr($vip['interface'], "lo0"))) {
384
					$oldvips[$vip['subnet']]['content'] =
385
					    $vip['interface'] .
386
					    $vip['subnet'] .
387
					    $vip['subnet_bits'];
388
					$oldvips[$vip['subnet']]['interface'] =
389
					    $vip['interface'];
390
					$oldvips[$vip['subnet']]['subnet'] =
391
					    $vip['subnet'];
392
				} else if (($vip['mode'] == "ipalias" ||
393
				    $vip['mode'] == 'proxyarp') &&
394
				    !(substr($vip['interface'], 0, 4) == '_vip')
395
				    || strstr($vip['interface'], "lo0")) {
396 51611440 Ermal
					$vipbackup[] = $vip;
397 c14781e3 Renato Botelho
				}
398 51611440 Ermal
			}
399 19b5c3e7 Ermal
		}
400 f51d4f98 Ermal
401 f81e7cc4 Renato Botelho
		/* For vip section, first keep items sent from the master */
402
		$config = array_merge_recursive_unique($config, $sections);
403 51611440 Ermal
404 7cab6335 Renato Botelho
		/* Remove local CP zones removed remote */
405
		foreach ($cp_to_del as $zone) {
406
			$cpzone = $zone;
407
			$cpzoneid = $config['captiveportal'][$cpzone]['zoneid'];
408
			unset($config['captiveportal'][$cpzone]['enable']);
409
			captiveportal_configure_zone(
410
			    $config['captiveportal'][$cpzone]);
411
			unset($config['captiveportal'][$cpzone]);
412
			if (isset($config['voucher'][$cpzone])) {
413
				unset($config['voucher'][$cpzone]);
414
			}
415
		}
416
417 b8963db6 Renato Botelho
		/* Remove locally items removed remote */
418
		foreach ($voucher as $zone => $item) {
419
			/* No rolls on master, delete local ones */
420
			if (!is_array($item['roll'])) {
421
				unset($config['voucher'][$zone]['roll']);
422
			}
423
		}
424
425
		$l_rolls = array();
426
		if (is_array($config['voucher'])) {
427
			foreach ($config['voucher'] as $zone => $item) {
428
				if (!is_array($item['roll'])) {
429
					continue;
430
				}
431
				foreach ($item['roll'] as $idx => $roll) {
432
					/* Make it easy to find roll by # */
433
					$l_rolls[$zone][$roll['number']] = $idx;
434
				}
435
			}
436
		}
437
438
		/*
439
		 * Process vouchers sent by primary node and:
440
		 * - Add new items
441
		 * - Update existing items based on 'lastsync' field
442
		 */
443
		foreach ($voucher as $zone => $item) {
444
			if (!is_array($item['roll'])) {
445
				continue;
446
			}
447
			foreach ($item['roll'] as $idx => $roll) {
448
				if (!isset($l_rolls[$zone][$roll['number']])) {
449
					$config['voucher'][$zone]['roll'][] =
450
					    $roll;
451
					continue;
452
				}
453
				$l_roll_idx = $l_rolls[$zone][$roll['number']];
454 c6c398c6 jim-p
				init_config_arr(array('voucher', $zone));
455 b8963db6 Renato Botelho
				$l_vouchers = &$config['voucher'][$zone];
456
				$l_roll = $l_vouchers['roll'][$l_roll_idx];
457
				if (!isset($l_roll['lastsync'])) {
458
					$l_roll['lastsync'] = 0;
459
				}
460
461
				if (isset($roll['lastsync']) &&
462
				    $roll['lastsync'] != $l_roll['lastsync']) {
463
					$l_vouchers['roll'][$l_roll_idx] =
464
					    $roll;
465
					unset($l_rolls[$zone][$roll['number']]);
466
				}
467
			}
468
		}
469
470
		/*
471
		 * At this point $l_rolls contains only items that are not
472
		 * present on primary node. They must be removed
473
		 */
474
		foreach ($l_rolls as $zone => $item) {
475
			foreach ($item as $number => $idx) {
476
				unset($config['voucher'][$zone][$idx]);
477
			}
478
		}
479
480 f81e7cc4 Renato Botelho
		/*
481
		 * Then add ipalias and proxyarp types already defined
482
		 * on the backup
483
		 */
484
		if (is_array($vipbackup) && !empty($vipbackup)) {
485
			if (!is_array($config['virtualip'])) {
486
				$config['virtualip'] = array();
487
			}
488
			if (!is_array($config['virtualip']['vip'])) {
489
				$config['virtualip']['vip'] = array();
490
			}
491
			foreach ($vipbackup as $vip) {
492
				array_unshift($config['virtualip']['vip'], $vip);
493
			}
494 962f215d Phil Davis
		}
495 51611440 Ermal
496 f81e7cc4 Renato Botelho
		/* Log what happened */
497 8cb29dac doktornotor
		$mergedkeys = implode(", ", array_merge(array_keys($sections),
498 f81e7cc4 Renato Botelho
		    $syncd_full_sections));
499
		write_config(sprintf(gettext(
500
		    "Merged in config (%s sections) from XMLRPC client."),
501
		    $mergedkeys));
502
503
		/*
504
		 * The real work on handling the vips specially
505
		 * This is a copy of intefaces_vips_configure with addition of
506
		 * not reloading existing/not changed carps
507
		 */
508
		if (isset($sections['virtualip']) &&
509
		    is_array($config['virtualip']) &&
510
		    is_array($config['virtualip']['vip'])) {
511
			$carp_setuped = false;
512
			$anyproxyarp = false;
513
514
			foreach ($config['virtualip']['vip'] as $vip) {
515
				$key = "{$vip['interface']}_vip{$vip['vhid']}";
516
517
				if ($vip['mode'] == "carp" &&
518
				    isset($oldvips[$key])) {
519
					if ($oldvips[$key]['content'] ==
520
					    $vip['password'] .
521
					    $vip['advskew'] .
522
					    $vip['subnet'] .
523
					    $vip['subnet_bits'] .
524
					    $vip['advbase'] &&
525
					    does_vip_exist($vip)) {
526
						unset($oldvips[$key]);
527
						/*
528
						 * Skip reconfiguring this vips
529
						 * since nothing has changed.
530
						 */
531
						continue;
532 19ed1624 Ermal
					}
533 5fda51cd jim-p
534 f81e7cc4 Renato Botelho
				} elseif ($vip['mode'] == "ipalias" &&
535 5fda51cd jim-p
				    (substr($vip['interface'], 0, 4) == '_vip'
536
				    || strstr($vip['interface'], "lo0")) &&
537 f81e7cc4 Renato Botelho
				    isset($oldvips[$vip['subnet']])) {
538
					$key = $vip['subnet'];
539
					if ($oldvips[$key]['content'] ==
540
					    $vip['interface'] .
541
					    $vip['subnet'] .
542
					    $vip['subnet_bits'] &&
543
					    does_vip_exist($vip)) {
544
						unset($oldvips[$key]);
545
						/*
546
						 * Skip reconfiguring this vips
547
						 * since nothing has changed.
548
						 */
549
						continue;
550 2708a5cf Ermal
					}
551 f81e7cc4 Renato Botelho
					unset($oldvips[$key]);
552 2708a5cf Ermal
				}
553 51611440 Ermal
554 f81e7cc4 Renato Botelho
				switch ($vip['mode']) {
555 962f215d Phil Davis
				case "proxyarp":
556
					$anyproxyarp = true;
557
					break;
558
				case "ipalias":
559
					interface_ipalias_configure($vip);
560
					break;
561
				case "carp":
562 f81e7cc4 Renato Botelho
					$carp_setuped = true;
563 962f215d Phil Davis
					interface_carp_configure($vip);
564
					break;
565 f81e7cc4 Renato Botelho
				}
566 51611440 Ermal
			}
567 f81e7cc4 Renato Botelho
568
			/* Cleanup remaining old carps */
569
			foreach ($oldvips as $oldvipar) {
570
				$oldvipif = get_real_interface(
571
				    $oldvipar['interface']);
572
573
				if (empty($oldvipif)) {
574
					continue;
575
				}
576
577 962f215d Phil Davis
				if (is_ipaddrv6($oldvipar['subnet'])) {
578 f81e7cc4 Renato Botelho
					 mwexec("/sbin/ifconfig " .
579
					     escapeshellarg($oldvipif) .
580
					     " inet6 " .
581
					     escapeshellarg($oldvipar['subnet']) .
582
					     " delete");
583 962f215d Phil Davis
				} else {
584 f81e7cc4 Renato Botelho
					pfSense_interface_deladdress($oldvipif,
585
					    $oldvipar['subnet']);
586 962f215d Phil Davis
				}
587 e3cffd6c Ermal LUÇI
			}
588 f81e7cc4 Renato Botelho
			if ($carp_setuped == true) {
589
				interfaces_sync_setup();
590
			}
591
			if ($anyproxyarp == true) {
592
				interface_proxyarp_configure();
593
			}
594 51611440 Ermal
		}
595 f81e7cc4 Renato Botelho
596
		if ($old_ipsec_enabled !== ipsec_enabled()) {
597
			vpn_ipsec_configure();
598 962f215d Phil Davis
		}
599 137f46d8 Ermal
600 f81e7cc4 Renato Botelho
		unset($old_config);
601
602 79f7bc7f Renato Botelho
		local_sync_accounts($u2add, $u2del, $g2add, $g2del);
603 7fead243 Renato Botelho
		$this->filter_configure(false);
604 79f7bc7f Renato Botelho
605 f81e7cc4 Renato Botelho
		return true;
606 962f215d Phil Davis
	}
607 d026178f Renato Botelho
608 f81e7cc4 Renato Botelho
	/**
609
	 * Merge items into installedpackages config section
610
	 *
611
	 * @param array $section
612
	 *
613
	 * @return bool
614
	 */
615 dc5f639f PiBa-NL
	public function merge_installedpackages_section($section) {
616
		$this->auth();
617 d026178f Renato Botelho
618 f81e7cc4 Renato Botelho
		global $config;
619 50d49018 Colin Smith
620 f81e7cc4 Renato Botelho
		if ($this->loop_detected) {
621
			log_error("Disallowing CARP sync loop");
622
			return true;
623
		}
624 82ae5cfc Scott Ullrich
625 f81e7cc4 Renato Botelho
		$config['installedpackages'] = array_merge(
626
		    $config['installedpackages'], $section);
627 8cb29dac doktornotor
		$mergedkeys = implode(", ", array_keys($section));
628 f81e7cc4 Renato Botelho
		write_config(sprintf(gettext(
629
		    "Merged in config (%s sections) from XMLRPC client."),
630
		    $mergedkeys));
631 137f46d8 Ermal
632 f81e7cc4 Renato Botelho
		return true;
633 fb0eb20b Ermal
	}
634 c87f4b70 Ermal
635 f81e7cc4 Renato Botelho
	/**
636
	 * Merge items into config
637
	 *
638
	 * @param array $section
639
	 *
640
	 * @return bool
641
	 */
642 dc5f639f PiBa-NL
	public function merge_config_section($section) {
643
		$this->auth();
644 137f46d8 Ermal
645 f81e7cc4 Renato Botelho
		global $config;
646 82ae5cfc Scott Ullrich
647 f81e7cc4 Renato Botelho
		if ($this->loop_detected) {
648
			log_error("Disallowing CARP sync loop");
649
			return true;
650
		}
651 dc1cd85d Scott Ullrich
652 f81e7cc4 Renato Botelho
		$config_new = $this->array_overlay($config, $section);
653
		$config = $config_new;
654 8cb29dac doktornotor
		$mergedkeys = implode(", ", array_keys($section));
655 f81e7cc4 Renato Botelho
		write_config(sprintf(gettext(
656
		    "Merged in config (%s sections) from XMLRPC client."),
657
		    $mergedkeys));
658 c87f4b70 Ermal
659 f81e7cc4 Renato Botelho
		return true;
660 fb0eb20b Ermal
	}
661 c87f4b70 Ermal
662 f81e7cc4 Renato Botelho
	/**
663
	 * Wrapper for filter_configure()
664
	 *
665
	 * @return bool
666 57b5da70 jim-p
	 */
667 79f7bc7f Renato Botelho
	public function filter_configure($reset_accounts = true) {
668 dc5f639f PiBa-NL
		$this->auth();
669 f81e7cc4 Renato Botelho
670
		global $g, $config;
671
672
		filter_configure();
673
		system_routing_configure();
674
		setup_gateways_monitor();
675
		require_once("openvpn.inc");
676
		openvpn_resync_all();
677
678
		/*
679
		 * The DNS Resolver and the DNS Forwarder may both be active so
680
		 * long as * they are running on different ports.
681
		 * See ticket #5882
682
		 */
683
		if (isset($config['dnsmasq']['enable'])) {
684
			/* Configure dnsmasq but tell it NOT to restart DHCP */
685
			services_dnsmasq_configure(false);
686
		} else {
687
			/* kill any running dnsmasq instance */
688
			if (isvalidpid("{$g['varrun_path']}/dnsmasq.pid")) {
689
				sigkillbypid("{$g['varrun_path']}/dnsmasq.pid",
690
				    "TERM");
691
			}
692 57b5da70 jim-p
		}
693 f81e7cc4 Renato Botelho
		if (isset($config['unbound']['enable'])) {
694
			/* Configure unbound but tell it NOT to restart DHCP */
695
			services_unbound_configure(false);
696
		} else {
697
			/* kill any running Unbound instance */
698
			if (isvalidpid("{$g['varrun_path']}/unbound.pid")) {
699
				sigkillbypid("{$g['varrun_path']}/unbound.pid",
700
				    "TERM");
701
			}
702 57b5da70 jim-p
		}
703 137f46d8 Ermal
704 f81e7cc4 Renato Botelho
		/*
705
		 * Call this separately since the above are manually set to
706
		 * skip the DHCP restart they normally perform.
707
		 * This avoids restarting dhcpd twice as described on
708
		 * ticket #3797
709
		 */
710
		services_dhcpd_configure();
711 137f46d8 Ermal
712 79f7bc7f Renato Botelho
		if ($reset_accounts) {
713
			local_reset_accounts();
714
		}
715 c87f4b70 Ermal
716 7cab6335 Renato Botelho
		captiveportal_configure();
717
718 f81e7cc4 Renato Botelho
		return true;
719 3dd2a278 Scott Ullrich
	}
720 137f46d8 Ermal
721 f81e7cc4 Renato Botelho
	/**
722
	 * Wrapper for configuring CARP interfaces
723
	 *
724
	 * @return bool
725
	 */
726 dc5f639f PiBa-NL
	public function interfaces_carp_configure() {
727
		$this->auth();
728 efe7562e Scott Ullrich
729 f81e7cc4 Renato Botelho
		if ($this->loop_detected) {
730
			log_error("Disallowing CARP sync loop");
731
			return true;
732
		}
733 0567899d Ermal
734 f81e7cc4 Renato Botelho
		interfaces_vips_configure();
735 e501de37 Ermal
736 f81e7cc4 Renato Botelho
		return true;
737
	}
738 e501de37 Ermal
739 f81e7cc4 Renato Botelho
	/**
740
	 * Wrapper for rc.reboot
741
	 *
742
	 * @return bool
743
	 */
744 dc5f639f PiBa-NL
	public function reboot() {
745
		$this->auth();
746 e501de37 Ermal
747 f81e7cc4 Renato Botelho
		mwexec_bg("/etc/rc.reboot");
748 137f46d8 Ermal
749 f81e7cc4 Renato Botelho
		return true;
750 3dd2a278 Scott Ullrich
	}
751 d9064267 Colin Smith
}
752
753 f3f98e97 Phil Davis
// run script until its done and can 'unlock' the xmlrpc.lock, this prevents hanging php-fpm / webgui
754 179377b0 robjarsen
ignore_user_abort(true);
755 8239af2d PiBa-NL
set_time_limit(0);
756
757 67d78c87 Ermal
$xmlrpclockkey = lock('xmlrpc', LOCK_EX);
758
759 f81e7cc4 Renato Botelho
XML_RPC2_Backend::setBackend('php');
760
$HTTP_RAW_POST_DATA = file_get_contents('php://input');
761
762
$options = array(
763
	'prefix' => 'pfsense.',
764
	'encoding' => 'utf-8',
765 4f78ae1d Renato Botelho
	'autoDocument' => false,
766 50d49018 Colin Smith
);
767 b298dd06 Scott Ullrich
768 f81e7cc4 Renato Botelho
$server = XML_RPC2_Server::create(new pfsense_xmlrpc_server(), $options);
769
$server->handleCall();
770 67d78c87 Ermal
771 f81e7cc4 Renato Botelho
unlock($xmlrpclockkey);
772 0b581a8a Scott Ullrich
773 de63649b Rafael Lucas
?>