legacy.inc 8.44 KB
Newer Older
1 2
<?php
/*
Ad Schellevis's avatar
Ad Schellevis committed
3 4 5 6
    Copyright (C) 2015-2016 Deciso B.V.
    Copyright (C) 2009, 2010 Scott Ullrich
    Copyright (C) 2005 Colin Smith
    All rights reserved.
7

Ad Schellevis's avatar
Ad Schellevis committed
8 9
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
10

Ad Schellevis's avatar
Ad Schellevis committed
11 12
    1. Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.
13

Ad Schellevis's avatar
Ad Schellevis committed
14 15 16
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
17

Ad Schellevis's avatar
Ad Schellevis committed
18 19 20 21 22 23 24 25 26 27
    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.
28 29 30 31 32 33
*/

/**
 * request functions which may be registered by the xmlrpc system
 * @return array
 */
Ad Schellevis's avatar
Ad Schellevis committed
34
function xmlrpc_publishable_legacy()
35
{
36
    $publish = array('filter_configure_xmlrpc','restore_config_section_xmlrpc','firmware_version_xmlrpc');
37

38
    return $publish;
39 40
}

41 42 43 44 45
/*
 * does_vip_exist($vip): return true or false if a vip is
 * configured.
 */
function does_vip_exist($vip) {
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    global $config;

    if(!$vip) {
        return false;
    }

    switch ($vip['mode']) {
        case "carp":
        case "ipalias":
            /* XXX: Make proper checks? */
            $realif = get_real_interface($vip['interface']);
            if (!does_interface_exist($realif)) {
                return false;
            }
            break;
        case "proxyarp":
            /* XXX: Implement this */
        default:
            return false;
    }

    $ifacedata = pfSense_getall_interface_addresses($realif);
    foreach ($ifacedata as $vipips) {
        if ($vipips == "{$vip['subnet']}/{$vip['subnet_bits']}") {
            return true;
        }
    }

    return false;
75 76
}

77
/**
78
 * merge attributes from source array to destination
79
 * updates leaves and overwrites sequenced arrays (container types).
80 81
 * @param array $cnf_source source data
 * @param array $cnf_dest target
82
 */
83
function merge_config_attributes(&$cnf_source, &$cnf_dest)
84
{
85 86
   foreach ($cnf_source as $cnf_key => &$cnf_value) {
       if (is_array($cnf_value)) {
87 88 89 90
           if (!isset($cnf_dest[$cnf_key]) || !is_array($cnf_dest[$cnf_key]) || // new
                (count($cnf_dest[$cnf_key]) > 0 && isset($cnf_dest[$cnf_key][0])) || // sequenced item
                (count($cnf_dest[$cnf_key]) > 0 && isset($cnf_dest[$cnf_key]['@attributes']['uuid'])) // mvc array
                ) {
91
               // (re)set destination array when new or containing a sequenced list of items
92 93 94 95 96 97 98
               $cnf_dest[$cnf_key] = array();
           }
           merge_config_attributes($cnf_value, $cnf_dest[$cnf_key]);
       } else {
           $cnf_dest[$cnf_key] = $cnf_value;
       }
   }
99 100 101 102 103 104 105 106
}

/**
 * retrieve firmware version
 * @return mixed
 */
function firmware_version_xmlrpc()
{
107
    require_once("pfsense-utils.inc");
108
    return host_firmware_version();
109
}
110 111 112 113 114 115 116 117


/**
 * filter reconfigure
 * @return mixed
 */
function filter_configure_xmlrpc()
{
118
    global $config;
119
    require_once("filter.inc");
Ad Schellevis's avatar
Ad Schellevis committed
120
    require_once("system.inc");
121
    require_once("interfaces.inc");
122 123 124
    require_once("vslb.inc");
    require_once("openvpn.inc");
    require_once("services.inc");
125
    require_once("rrd.inc");
126
    require_once('pfsense-utils.inc');
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

    filter_configure();
    system_routing_configure();
    setup_gateways_monitor();
    relayd_configure();
    openvpn_resync_all();
    if (isset($config['dnsmasq']['enable'])) {
        services_dnsmasq_configure();
    } elseif (isset($config['unbound']['enable'])) {
        services_unbound_configure();
    } else {
        # Both calls above run services_dhcpd_configure(), then we just
        # need to call it when them are not called to avoid restart dhcpd
        # twice, as described on ticket #3797
        services_dhcpd_configure();
    }
143
    system_hosts_generate();
144 145 146 147 148
    local_sync_accounts();

    return true;
}

149 150 151 152 153 154 155 156
/**
 * restore config section
 * @param $new_config
 * @return bool
 */
function restore_config_section_xmlrpc($new_config)
{
    global $config;
157

158
    require_once("interfaces.inc");
159
    require_once("filter.inc");
160
    require_once("ipsec.inc");
161

162
    // save old config
163 164
    $old_config = $config;

165 166 167 168
    // Some sections should just be copied and not merged, namely if there's a risk of attributes being removed
    // without being seen by the remote remote (backup) side.
    // (ipsec, openvpn, nat can probably moved out later by specifying a better path to the attribute)
    $sync_full = array('ipsec', 'wol', 'dnsmasq', 'load_balancer', 'openvpn', 'nat', 'dhcpd', 'dhcpv6');
169 170 171 172 173 174 175 176 177 178 179
    $sync_full_done = array();
    foreach ($sync_full as $syncfull) {
        if (isset($new_config[$syncfull])) {
            $config[$syncfull] = $new_config[$syncfull];
            unset($new_config[$syncfull]);
            $sync_full_done[] = $syncfull;
        }
    }

    $vipbackup = array();
    $oldvips = array();
180
    if (isset($new_config['virtualip']['vip']) && isset($config['virtualip']['vip'])) {
181 182
        foreach ($config['virtualip']['vip'] as $vipindex => $vip) {
            if ($vip['mode'] == "carp") {
183 184 185
                // rc.filter_synchronize only sends carp vips, keep the rest like it was
                $oldvips["{$vip['interface']}_vip{$vip['vhid']}"] = $vip ;
            } else {
186
                $vipbackup[] = $vip;
187 188 189 190
            }
        }
    }

191 192
    // merge config attributes.
    merge_config_attributes($new_config, $config);
193

194
    if (count($vipbackup) > 0) {
195
        // if $new_config contained VIPS and the old config contained non carp vips, prepend original vips
196 197 198 199 200 201 202 203 204 205
        foreach ($vipbackup as $vip) {
            array_unshift($config['virtualip']['vip'], $vip);
        }
    }

    /* Log what happened */
    $mergedkeys = implode(",", array_merge(array_keys($new_config), $sync_full_done));
    write_config(sprintf(gettext("Merged in config (%s sections) from XMLRPC client."), $mergedkeys));

    /*
206
     * Handle virtual ips
207
     */
208
    if (isset($new_config['virtualip']['vip'])) {
209 210
        $carp_setuped = false;
        $anyproxyarp = false;
211 212 213
        if (isset($config['virtualip']['vip'])) {
          foreach ($config['virtualip']['vip'] as $vip) {
              if ($vip['mode'] == "carp" && isset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"])) {
214 215 216 217 218
                  $is_changed = false;
                  foreach (array('password', 'advskew', 'subnet', 'subnet_bits', 'advbase') as $chk_key) {
                      if ($oldvips["{$vip['interface']}_vip{$vip['vhid']}"][$chk_key] != $vip[$chk_key]) {
                          $is_changed = true;
                          break;
219 220
                      }
                  }
221 222
                  if (!$is_changed) {
                      unset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"]);
223 224 225 226 227 228 229 230 231 232 233 234 235 236
                      if (does_vip_exist($vip)) {
                          continue; // Skip reconfiguring this vips since nothing has changed.
                      }
                  }
              }

              switch ($vip['mode']) {
                  case "proxyarp":
                      $anyproxyarp = true;
                      break;
                  case "ipalias":
                      interface_ipalias_configure($vip);
                      break;
                  case "carp":
237
                      $carp_setuped = true;
238 239 240 241
                      interface_carp_configure($vip);
                      break;
              }
          }
242
        }
243 244 245 246 247 248

        // remove old (carp) virtual ip's
        foreach ($oldvips as $oldvip) {
            interface_vip_bring_down($oldvip);
        }

249 250 251 252 253 254 255 256 257 258 259
        if ($carp_setuped) {
            interfaces_carp_setup();
        }

        if ($anyproxyarp) {
            interface_proxyarp_configure();
        }

    }

    if (isset($old_config['ipsec']['enable']) !== isset($config['ipsec']['enable'])) {
260
        ipsec_configure();
261 262 263 264 265 266
    }

    unset($old_config);

    return true;
}