libreschool-pxeserver/root/srv/ipxe/boot.php

138 lines
3.3 KiB
PHP

<?php
/**
* LibreSchool PXEServer dispatcher
*
* This script manages the loading of the PXE image, based on specific
* host preferences.
*
* @category Client_Management
* @package Libreschool
* @author Paolo Asperti <paolo@asperti.com>
* @copyright 2020 The LibreSchool project
* @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL-3.0
* @version GIT: $Id$
* @link https://git.libreschool.org/LibreSchool/libreschool-pxeserver
*/
require_once "EsmithDatabase.php";
$hosts_db = new EsmithDatabase('hosts');
/**
* Check if specified mac address is valid
*
* We should've used filter_var($mac, FILTER_VALIDATE_MAC) but it's available
* from PHP 5.5.0 and we have 5.4.16. Too bad.
*
* @param string $mac the mac address to examine
*
* @return bool if the macaddress is valid or not
*/
function isValidMAC($mac) {
if (preg_match('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', $mac)) {
// 01:23:45:67:89:ab
return true;
} elseif (preg_match('/^([a-fA-F0-9]{2}\-){5}[a-fA-F0-9]{2}$/', $mac)) {
// 01-23-45-67-89-ab
return true;
} elseif (preg_match('/^[a-fA-F0-9]{12}$/', $mac)) {
// 0123456789ab
return true;
} else if (preg_match('/^([a-fA-F0-9]{4}\.){2}[a-fA-F0-9]{4}$/', $mac)) {
// 0123.4567.89ab
return true;
} else {
return false;
}
}
/**
* Get the client corresponding a specific mac address
*
* @param string $mac the mac address of the client
*
* @return host||boolean client if found, false otherwise
*/
function getClientFromMAC($mac=false) {
global $hosts_db;
$hosts = $hosts_db->getAllByProp('MacAddress', $mac);
if (count($hosts)>0) {
return array_pop($hosts);
} else {
return false;
}
}
/**
* Default exit string
* This string will instruct to reload the script
* passing the mac address of the calling machine
*
* @return null
*/
function defaultExit() {
print("#!ipxe
chain http://".$_SERVER['HTTP_HOST'].$_SERVER["SCRIPT_NAME"]."?mac=\${mac}
");
exit();
}
/**
* Check if specified PXE image exists
*
* @param string $i image name
*
* @return bool if the image exists or not
*/
function imageExists($i) {
$pwd = dirname(__FILE__);
$dir = $pwd . '/' . $i;
$bootfile = $dir . '/boot';
return is_dir($dir) && is_readable($bootfile);
}
if (!isset($_REQUEST['mac'])) {
defaultExit();
}
if (empty($_REQUEST['mac'])) {
defaultExit();
}
if (!isValidMAC($_REQUEST['mac'])) {
defaultExit();
}
$mac = $_REQUEST['mac'];
$client = getClientFromMAC($mac);
if (!$client) {
defaultExit();
}
if (isset($client['PXEImageOneTime']) && !empty($client['PXEImageOneTime'])) {
// try to boot the OneTime image
if (imageExists($client['PXEImageOneTime'])) {
print("#!ipxe
chain " . $client['PXEImageOneTime'] . "/boot
");
$props = array(
'PXEImageOneTime' => ''
);
$hosts_db->setProp($client['name'], $props);
exit();
}
}
if (isset($client['PXEImage']) && !empty($client['PXEImage'])) {
// try to boot the standard image
if (imageExists($client['PXEImage'])) {
print("#!ipxe
chain " . $client['PXEImage'] . "/boot
");
exit();
}
}
print("#!ipxe
chain localhd/boot
");