149 lines
3.6 KiB
PHP
149 lines
3.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* LibreSchool PXEServer dispatcher
|
|
*
|
|
* This script manages the loading of the PXE image, based on specific
|
|
* host preferences.
|
|
*
|
|
* php version 5.4.16
|
|
*
|
|
* @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
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
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
|
|
# reload with mac address
|
|
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';
|
|
$iso_is_mounted = $dir . '/iso_is_mounted';
|
|
$iso_ok = ! file_exists($iso_is_mounted) ||
|
|
(is_link($iso_is_mounted) && is_readable($iso_is_mounted));
|
|
return is_dir($dir) && is_readable($bootfile) && $iso_ok;
|
|
}
|
|
|
|
if (!isset($_REQUEST['mac'])) {
|
|
defaultExit();
|
|
}
|
|
if (empty($_REQUEST['mac'])) {
|
|
defaultExit();
|
|
}
|
|
if (!isValidMAC($_REQUEST['mac'])) {
|
|
defaultExit();
|
|
}
|
|
$mac = $_REQUEST['mac'];
|
|
$client = getClientFromMAC($mac);
|
|
if (!$client) {
|
|
// TODO: make up a default for unknown clients
|
|
defaultExit();
|
|
}
|
|
|
|
if (isset($client['PXEImageOneTime']) && !empty($client['PXEImageOneTime'])) {
|
|
// try to boot the OneTime image
|
|
if (imageExists($client['PXEImageOneTime'])) {
|
|
print("#!ipxe
|
|
# Loading PXEImageOneTime
|
|
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
|
|
# Loading PXEImage
|
|
chain " . $client['PXEImage'] . "/boot
|
|
");
|
|
exit();
|
|
}
|
|
}
|
|
|
|
print("#!ipxe
|
|
# catchall
|
|
chain localhd/boot
|
|
");
|