Project

General

Profile

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