196 lines
6.4 KiB
PHP
196 lines
6.4 KiB
PHP
<?php
|
||
# helper function for linked OUs
|
||
function getLinkedOUs(string $gpo): array|false
|
||
{
|
||
$encodedGpo = rawurlencode($gpo);
|
||
$requestUrl = "http://172.17.0.1:5000/linked_ous?gpo={$encodedGpo}";
|
||
$ch = curl_init($requestUrl);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||
$rawResponse = curl_exec($ch);
|
||
if ($rawResponse === false) {
|
||
error_log('cURL error [' . curl_errno($ch) . ']: ' . curl_error($ch));
|
||
curl_close($ch);
|
||
return false;
|
||
}
|
||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||
if ($httpCode !== 200) {
|
||
error_log("API returned HTTP {$httpCode} for GPO '{$gpo}'");
|
||
curl_close($ch);
|
||
return false;
|
||
}
|
||
curl_close($ch);
|
||
$decoded = json_decode($rawResponse, true);
|
||
if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
|
||
error_log('JSON decode error: ' . json_last_error_msg());
|
||
return false;
|
||
}
|
||
return $decoded;
|
||
//return implode("\n", $decoded);
|
||
}
|
||
|
||
$yaml_timestamp = json_decode(file_get_contents('http://172.17.0.1:5000/timestamp'), true);
|
||
$gpo_links = json_decode(file_get_contents('http://172.17.0.1:5000/gpo_links'), true);
|
||
$index_duration = json_decode(file_get_contents('http://172.17.0.1:5000/index_duration'), true);
|
||
|
||
?>
|
||
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>GPO Query</title>
|
||
<link rel="stylesheet" href="styles.css">
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h2>Query GPOs by Group</h2>
|
||
This tool is intended to help determine what OU to use for a specific group.<br>
|
||
Users often request systems with a certain security group assigned.<br>
|
||
Since AD has no way to look this up, this makes it challenging to match groups to OUs.<p>
|
||
This site has all restricted groups indexed by GPO and OU.<br>
|
||
Search is case insensitive and supports partial match. <br>
|
||
The OUs liked to the GPOs will show up as a hover tooltip on the GPO name.<br>
|
||
Clicking on the GPO name will list all linked OUs.<br><p>
|
||
</div>
|
||
<div class="container">
|
||
|
||
<?php
|
||
// populating the info div
|
||
// if the group var is set, show the GPOs with the search term
|
||
if (isset($_GET['group'])) {
|
||
echo '
|
||
<form action="index.php" method="GET">
|
||
<label for="group">Group Name:</label>
|
||
<input type="text" id="group" name="group" value="'.htmlspecialchars($_GET['group']).'" required>
|
||
<button type="submit">Query</button><br>
|
||
</form><p>
|
||
Return <a href=/>Home</a><br>
|
||
';
|
||
$group = urlencode($_GET['group']);
|
||
$url = "http://172.17.0.1:5000/gpo?group=$group";
|
||
// query API
|
||
$ch = curl_init();
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($ch, CURLOPT_URL, $url);
|
||
$response = curl_exec($ch);
|
||
if ($e = curl_error($ch)) {
|
||
die("Curl error: $e");
|
||
}
|
||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||
if ($httpCode != 200) {
|
||
die("Error: Received HTTP code $httpCode");
|
||
}
|
||
curl_close($ch);
|
||
$data = json_decode($response, true);
|
||
$numResults = count($data);
|
||
// build the group array
|
||
$gpoMap = []; // will look like: [ 'GPO‑Name' => ['Administrator' => [...], 'vnc_admin' => [...]] ]
|
||
|
||
if (isset($data['error'])) {
|
||
echo "<p>Error: {$data['error']}</p>";
|
||
}
|
||
else {
|
||
foreach ($data as $row) {
|
||
// safety: skip rows that do not contain the expected keys
|
||
if (!isset($row['gpo'], $row['ad_group'], $row['local_group'])) {
|
||
continue;
|
||
}
|
||
$gpoName = $row['gpo'];
|
||
$adGroup = $row['ad_group'];
|
||
$localGroup = strtolower($row['local_group']);
|
||
// initialise if not already done
|
||
if (!isset($gpoMap[$gpoName])) {
|
||
$gpoMap[$gpoName] = [
|
||
'administrators' => [],
|
||
'vnc_admin' => []
|
||
];
|
||
}
|
||
// put the ad_group into the right bucket
|
||
if ($localGroup === 'administrators') {
|
||
$gpoMap[$gpoName]['administrators'][] = $adGroup;
|
||
} elseif ($localGroup === 'vnc_admin') {
|
||
$gpoMap[$gpoName]['vnc_admin'][] = $adGroup;
|
||
}
|
||
}
|
||
ksort($gpoMap, SORT_STRING | SORT_FLAG_CASE);
|
||
if($numResults > 0){
|
||
echo '
|
||
Total results: '.$numResults.'<br>
|
||
Data indexed at '.$yaml_timestamp['timestamp'].' after '.$index_duration['duration'].' minutes<br>
|
||
Total Linked GPOs: '.$gpo_links['gpo_links'].'<p>
|
||
<table border="1" cellpadding="4" cellspacing="0">
|
||
<tr>
|
||
<th>
|
||
GPO
|
||
</th>
|
||
<th>
|
||
Administrators
|
||
</th>
|
||
<th>
|
||
vnc_admin
|
||
</th>
|
||
</tr>
|
||
';
|
||
foreach ($gpoMap as $gpoName => $cols) {
|
||
// Remove duplicates and build comma‑separated lists
|
||
$adminGroups = implode('<br>', array_unique($cols['administrators']));
|
||
$vncGroups = implode('<br>', array_unique($cols['vnc_admin']));
|
||
$linkedOUs = implode("\n", getLinkedOUs($gpoName));
|
||
echo "
|
||
<tr>
|
||
<td>
|
||
<div title='$linkedOUs'>
|
||
<a href=/?gpo=$gpoName>{$gpoName}</a>
|
||
</div>
|
||
</td>
|
||
<td>
|
||
{$adminGroups}
|
||
</td>
|
||
<td>
|
||
{$vncGroups}
|
||
</td>
|
||
</tr>
|
||
";
|
||
}
|
||
echo '</table>
|
||
';
|
||
}
|
||
else{
|
||
echo 'No results found for query <b>'.$_GET['group'].'</b>.<p>';
|
||
}
|
||
}
|
||
}
|
||
|
||
// if you click on a GPO name, print all OUs
|
||
else if (isset($_GET['gpo'])) {
|
||
echo 'OUs linked to GPO <b>'.$_GET['gpo'].':</b><p><ul>';
|
||
$LinkedOUs = getLinkedOUs($_GET['gpo']);
|
||
foreach ($LinkedOUs as $OU){
|
||
echo "<li>".$OU."</li>";
|
||
}
|
||
#echo implode("<li>", $LinkedOUs);
|
||
echo '</ul><p>Return <a href=/>Home</a>';
|
||
|
||
}
|
||
|
||
else {
|
||
echo '
|
||
<form action="index.php" method="GET">
|
||
<label for="group">Group Name:</label>
|
||
<input type="text" id="group" name="group" required>
|
||
<button type="submit">Query</button>
|
||
</form><p>
|
||
Data indexed at '.$yaml_timestamp['timestamp'].' after '.$index_duration['duration'].' minutes<br>
|
||
Total Linked GPOs: '.$gpo_links['gpo_links'].'<p>
|
||
No group specified.</p>
|
||
';
|
||
|
||
}
|
||
echo "</div>
|
||
";
|
||
//echo "<p>Source code can be found <a target='_blank' rel='noopener noreferrer' href='https://gitea.matt-cloud.com/matt/gpo_lookup'>here</a>.<p>";
|
||
?>
|
||
|
||
</body>
|
||
</html>
|