summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2016-06-16 16:14:42 +0200
committerSimon Rettberg2016-06-16 16:14:42 +0200
commit872de4e07609d8dae7660e467a73fc6f4061956a (patch)
treea0f856c659e71b1ff7e57883ad1f071e23a50e67
parentDon't need these anymore (diff)
downloadslx-admin-872de4e07609d8dae7660e467a73fc6f4061956a.tar.gz
slx-admin-872de4e07609d8dae7660e467a73fc6f4061956a.tar.xz
slx-admin-872de4e07609d8dae7660e467a73fc6f4061956a.zip
[locations] Handle machine UUID param to determine location
-rw-r--r--modules-available/baseconfig/api.inc.php14
-rw-r--r--modules-available/locations/baseconfig/getconfig.inc.php6
-rw-r--r--modules-available/locations/inc/location.inc.php54
3 files changed, 66 insertions, 8 deletions
diff --git a/modules-available/baseconfig/api.inc.php b/modules-available/baseconfig/api.inc.php
index 000015f5..877ff4a7 100644
--- a/modules-available/baseconfig/api.inc.php
+++ b/modules-available/baseconfig/api.inc.php
@@ -5,10 +5,9 @@ if (substr($ip, 0, 7) === '::ffff:') {
$ip = substr($ip, 7);
}
-// TODO: Handle UUID in appropriate modules (optional)
-$uuid = Request::post('uuid', '', 'string');
-if (strlen($uuid) !== 36) {
- // Probably invalid UUID. What to do? Set empty or ignore?
+$uuid = Request::any('uuid', false, 'string');
+if ($uuid !== false && strlen($uuid) !== 36) {
+ $uuid = false;
}
/**
@@ -31,6 +30,11 @@ function escape($string)
*/
$configVars = array();
+function handleModule($file, $ip, $uuid) // Pass ip and uuid instead of global to make them read only
+{
+ global $configVars;
+ include $file;
+}
// Handle any hooks by other modules first
// other modules should generally only populate $configVars
@@ -38,7 +42,7 @@ foreach (glob('modules/*/baseconfig/getconfig.inc.php') as $file) {
preg_match('#^modules/([^/]+)/#', $file, $out);
if (!Module::isAvailable($out[1]))
continue;
- include $file;
+ handleModule($file, $ip, $uuid);
}
// Rest is handled by module
diff --git a/modules-available/locations/baseconfig/getconfig.inc.php b/modules-available/locations/baseconfig/getconfig.inc.php
index 2cf5495d..3a0c918f 100644
--- a/modules-available/locations/baseconfig/getconfig.inc.php
+++ b/modules-available/locations/baseconfig/getconfig.inc.php
@@ -8,11 +8,11 @@ if (Request::any('force', 0, 'int') === 1 && Request::any('module', false, 'stri
$locationId = Request::any('value', 0, 'int');
}
}
-// TODO: machine specific mapping
+
if ($locationId === false) {
- // Fallback to subnets
- $locationId = Location::getFromIp($ip);
+ $locationId = Location::getFromIpAndUuid($ip, $uuid);
}
+
$matchingLocations = array();
if ($locationId !== false) {
// Get all parents
diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php
index 3a282df1..bd642a57 100644
--- a/modules-available/locations/inc/location.inc.php
+++ b/modules-available/locations/inc/location.inc.php
@@ -154,6 +154,22 @@ class Location
}
/**
+ * Get location id for given machine (by uuid)
+ * @param $uuid machine uuid
+ * @return bool|int locationid, false if no match
+ */
+ public static function getFromMachineUuid($uuid)
+ {
+ // Only if we have the statistics module which supplies the machine table
+ if (Module::get('statistics') === false)
+ return false;
+ $ret = Database::queryFirst("SELECT locationid FROM machine WHERE machineuuid = :uuid", compact('uuid'));
+ if ($ret === false)
+ return false;
+ return (int)$ret['locationid'];
+ }
+
+ /**
* Get closest location by matching subnets. Deepest match in tree wins.
*
* @param string $ip IP address of client
@@ -178,6 +194,44 @@ class Location
}
/**
+ * Combined "intelligent" fetching of locationId by IP and UUID of
+ * client. We can't trust the UUID too much as it is provided by the
+ * client, so if it seems too fishy, the UUID will be ignored.
+ *
+ * @param $ip IP address of client
+ * @param $uuid System-UUID of client
+ * @return int|bool location id, or false if none matches
+ */
+ public static function getFromIpAndUuid($ip, $uuid)
+ {
+ $locationId = false;
+ $ipLoc = self::getFromIp($ip);
+ if ($ipLoc !== false && $uuid !== false) {
+ // Machine ip maps to a location, and we have a client supplied uuid
+ $uuidLoc = self::getFromMachineUuid($uuid);
+ if ($uuidLoc !== false) {
+ // Validate that the location the IP maps to is in the chain we get using the
+ // location determined by the uuid
+ $uuidLocations = self::getLocationRootChain($uuidLoc);
+ $ipLocations = self::getLocationRootChain($ipLoc);
+ if (in_array($uuidLoc, $ipLocations)
+ || (in_array($ipLoc, $uuidLocations) && count($ipLocations) + 1 >= count($uuidLocations))
+ ) {
+ // Close enough, allow
+ $locationId = $uuidLoc;
+ } else {
+ // UUID and IP disagree too much, play safe and ignore the UUID
+ $locationId = $ipLoc;
+ }
+ }
+ } else if ($ipLoc !== false) {
+ // No uuid, but ip maps to location; use that
+ $locationId = $ipLoc;
+ }
+ return $locationId;
+ }
+
+ /**
* Get all location IDs from the given location up to the root.
*
* @param int $locationId