function log_truncate() { global $COLLATE; global $dbo; include "include/validation_functions.php"; if (isset($_GET['action'])) { $action = clean($_GET['action']); } else { $action = "show warning"; } if ($action != "truncate") { // Show confirmation form require_once './include/header.php'; echo $COLLATE['languages']['selected']['confirmtruncate'] . " \n" . "<br /><br /><a href=\"logs.php?op=truncate&action=truncate\">" . "<img src=\"./images/apply.gif\" alt=\"" . $COLLATE['languages']['selected']['altconfirm'] . "\" /></a> <a href=\"logs.php\">" . "<img src=\"./images/cancel.gif\" alt=\"" . $COLLATE['languages']['selected']['altcancel'] . "\" /></a>"; require_once './include/footer.php'; exit; } // They've confirmed they want to truncate the logs. $sql = "SELECT MAX(id) FROM logs"; $result = $dbo->query($sql); $maxid = $result->fetchColumn(); $id = $maxid - 500; $sql = "DELETE FROM logs WHERE id<'{$id}'"; $dbo->query($sql); $level = "5"; $message = "LOGS TRUNCATED"; collate_log($level, $message); $notice = "truncatesuccess-notice"; header("Location: logs.php?notice={$notice}"); exit; }
function AccessControl($accesslevel, $message, $redirect = true) { /** * The goal of this section is to compare $_SESSION['accesslevel'] with the $accesslevel * parameter and allow or deny access. Each function has a hard-coded value * to check for to allow the function to run. When AccessControl has determined the * user has enough access for the function, it will stop further checks. * * Access Level 0 = Access denied completely: User can see index.php and login.php (this is the default for a new user) * Access Level 1 = Read-Only access, no changes can be made * Access Level 2 = Can make changes to statics table * Access Level 3 = Can make changes to subnets table + level 2 * Access Level 4 = Can make changes to blocks table + level 3 * Access Level 5 = Full control of the application including setting changes, user's access level modifications, and user password resets. * * $message is the message to be logged on success * $redirect is whether to redirect the user on access failure or output the error message and exit */ global $COLLATE; if ($accesslevel < $COLLATE['settings']['perms']) { // We're not requiring log-in or logging return true; } elseif (!isset($_SESSION['username'])) { // the user isn't logged in. $notice = "login-notice"; if ($redirect === true) { $returnto = urlencode($_SERVER['REQUEST_URI']); // return the user to where they came from with this var header("Location: login.php?notice={$notice}&returnto={$returnto}"); exit; } else { header("HTTP/1.1 401 Unauthorized"); echo $COLLATE['languages']['selected'][$notice]; exit; } } elseif ($_SESSION['accesslevel'] >= $accesslevel) { if ($accesslevel > "1") { collate_log($accesslevel, $message); } return true; // Access is allowed } // if we've gotten this far in the function, we've not met any condition to allow access so access is denied. $notice = "perms-notice"; if ($redirect === false) { header("HTTP/1.1 401 Unauthorized"); echo $COLLATE['languages']['selected'][$notice]; exit; } else { $referer = $_SERVER['HTTP_REFERER']; if (stristr($referer, "?") == TRUE) { header("Location: {$referer}¬ice={$notice}"); } else { header("Location: {$referer}?notice={$notice}"); } } exit; }
function delete_user() { global $COLLATE; global $username; global $dbo; collate_log('5', "User deleted: {$username}"); $sql = "DELETE FROM users WHERE username='******'"; $result = $dbo->query($sql); $message = str_replace("%username%", "{$username}", $COLLATE['languages']['selected']['userdeleted']); echo $message; exit; }
function toggle_stalescan() { global $COLLATE; global $dbo; $subnet_id = isset($_GET['subnet_id']) && preg_match("/[0-9]*/", $_GET['subnet_id']) ? $_GET['subnet_id'] : ''; $toggle = isset($_GET['toggle']) && preg_match("/on|off/", $_GET['toggle']) ? $_GET['toggle'] : ''; if (empty($subnet_id) || empty($toggle)) { header("HTTP/1.1 400 Bad Request"); $notice = 'invalidrequest'; header("Location: subnets.php?op=modify&subnet_id={$subnet_id}¬ice={$notice}"); exit; } $sql = "SELECT name, start_ip, mask FROM subnets WHERE id='{$subnet_id}'"; $query_result = $dbo->query($sql); if ($query_result->rowCount() !== 1) { header("HTTP/1.1 400 Bad Request"); $notice = 'invalidrequest'; header("Location: subnets.php?op=modify&subnet_id={$subnet_id}¬ice={$notice}"); exit; } list($subnet_name, $long_start_ip, $long_mask) = $query_result->fetch(PDO::FETCH_NUM); $cidr = subnet2cidr($long_start_ip, $long_mask); collate_log('3', "Stale Scan toggled {$toggle} for Subnet: {$subnet_name} ({$cidr})"); if ($toggle == 'on') { $stalescan_enabled = '1'; $notice = 'staletoggleon-notice'; $sql = "UPDATE statics SET failed_scans='0' WHERE subnet_id='{$subnet_id}'"; $dbo->query($sql); } else { $stalescan_enabled = '0'; $notice = 'staletoggleoff-notice'; $sql = "UPDATE statics SET failed_scans='-1' WHERE subnet_id='{$subnet_id}'"; $dbo->query($sql); } $sql = "UPDATE subnets SET stalescan_enabled={$stalescan_enabled} WHERE id='{$subnet_id}'"; $dbo->query($sql); header("Location: subnets.php?op=modify&subnet_id={$subnet_id}¬ice={$notice}"); exit; }
function toggle_stalescan() { global $COLLATE; global $dbo; $static_ip = isset($_GET['static_ip']) ? $_GET['static_ip'] : ''; $long_ip = ip2decimal($static_ip); $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : './search.php?notice='; if (stristr($referer, 'notice')) { $referer = preg_replace("/¬ice=.*/", "", $referer); } $referer = $referer . '¬ice='; if (empty($long_ip) || $long_ip === false) { header("HTTP/1.1 400 Bad Request"); echo "test1"; exit; } # make sure we aren't being asked to toggle for a subnet that has stale scan disabled: $sql = "SELECT stalescan_enabled FROM subnets WHERE \r\n CAST('{$long_ip}' & 0xFFFFFFFF AS UNSIGNED) & CAST(mask & 0xFFFFFFFF AS UNSIGNED) = CAST(start_ip & 0xFFFFFFFF AS UNSIGNED)"; $result = $dbo->query($sql); $subnet_status = $result->fetchColumn(); if ($subnet_status == false) { header("HTTP/1.1 400 Bad Request"); exit; } $sql = "SELECT failed_scans from statics where ip='{$long_ip}'"; $result = $dbo->query($sql); $current_count = $result->fetchColumn(); if ($current_count == -1) { $new_status = 'on'; $new_count = 0; $new_icon = 'scanning.png'; $new_icon_text = $COLLATE['languages']['selected']['disablestalescan']; } else { $new_status = 'off'; $new_count = -1; $new_icon = 'skipping.png'; $new_icon_text = $COLLATE['languages']['selected']['enablestalescan']; } collate_log('2', "Stale Scan toggled {$new_status} for IP: {$static_ip}"); $sql = "UPDATE statics SET failed_scans='{$new_count}' WHERE ip='{$long_ip}' LIMIT 1"; $dbo->query($sql); echo "<img src=\"./images/{$new_icon}\" alt=\"\" title=\"{$new_icon_text}\" />"; exit; }
function change_api_key_status() { global $COLLATE; $dbo = getdbo(); include 'include/validation_functions.php'; $apikey = isset($_GET['apikey']) ? $_GET['apikey'] : ''; $status = isset($_GET['status']) ? $_GET['status'] : ''; if (empty($apikey) || empty($status) || !preg_match("/active|revoked/", $status)) { header("HTTP/1.1 400 Bad Request"); echo $COLLATE['languages']['selected']['invalidrequest']; exit; } $return = validate_api_key($apikey); if ($return['0'] === false) { header("HTTP/1.1 400 Bad Request"); echo $COLLATE['languages']['selected'][$return['error']]; exit; } else { $description = $return['description']; $old_status = $return['active']; } $status = $status == 'active' ? true : false; $status_action = $status === true ? "activated" : "revoked"; $message = $status === true ? $COLLATE['languages']['selected']['keyactivated'] : $COLLATE['languages']['selected']['keyrevoked']; if ($status === $old_status) { exit; } $sql = "update `api-keys` set active='{$status}' where apikey='{$apikey}'"; $dbo->query($sql); collate_log('5', "Settings Updated: API key with description \"{$description}\" has been {$status_action}"); echo $message; exit; }
function process_file() { global $COLLATE; global $dbo; include "include/header.php"; include "include/validation_functions.php"; echo "<h1>Upload Results</h1><br />"; $uploaderror = isset($_FILES['file']['error']) ? $_FILES['file']['error'] : "UPLOAD_ERR_NO_FILE"; if ($uploaderror != "UPLOAD_ERR_OK") { echo "<p><b>" . $COLLATE['languages']['selected']['erroroccured'] . ":</b> "; switch ($uploaderror) { case "UPLOAD_ERR_INI_SIZE": echo $COLLATE['languages']['selected']['uploadtoobig']; break; case "UPLOAD_ERR_FORM_SIZE": echo $COLLATE['languages']['selected']['uploadtoobig']; break; case "UPLOAD_ERR_PARTIAL": echo $COLLATE['languages']['selected']['partialupload']; break; case "UPLOAD_ERR_NO_FILE": echo $COLLATE['languages']['selected']['noupload']; break; case "UPLOAD_ERR_NO_TMP_DIR": echo $COLLATE['languages']['selected']['notmpfolder']; break; case "UPLOAD_ERR_CANT_WRITE": echo $COLLATE['languages']['selected']['diskwritefail']; break; case "UPLOAD_ERR_EXTENSION": echo $COLLATE['languages']['selected']['extensionfail']; break; default: echo $COLLATE['languages']['selected']['unknownerror']; break; } echo "</p><br /><p><a href=\"command.php\">" . $COLLATE['languages']['selected']['tryagain'] . "</a></p>"; include "include/footer.php"; exit; } $file = $_FILES['file']['tmp_name']; $errorcount = '0'; $sql = ''; ini_set('auto_detect_line_endings', TRUE); if (($handle = fopen($file, "r")) !== FALSE) { // forcing the user to order the rows in the CSV file is a little burdensome // to enable the rows to be in any order, we load the file into an array, then // iterate over the array once per record type // The whole thing is done inside an SQL transaction. if any errors are found // at any point, the transaction is rolled back. $rownum = '0'; $checkedlinewithcontentforencoding = false; while ($currentrow = fgetcsv($handle, '1000', ",", "'")) { #if(($currentrow['0'] === null || preg_match('/^\s*$/', $currentrow['0'])) && count($currentrow) === '1'){ if ($currentrow['0'] === null || preg_match('/^\\s*$/', $currentrow['0'])) { // blank line in csv file $rownum++; continue; } if ($checkedlinewithcontentforencoding === false) { $characterencoding = mb_detect_encoding($currentrow['0']); if ($characterencoding != "ASCII") { echo "<p>" . $COLLATE['languages']['selected']['badencoding'] . "</p>"; echo "<br /><p><a href=\"command.php\">" . $COLLATE['languages']['selected']['tryagain'] . "</a></p>"; include "include/footer.php"; exit; } $checkedlinewithcontentforencoding = true; } if ($currentrow === false || $currentrow['0'] != 'block' && $currentrow['0'] != 'subnet' && $currentrow['0'] != 'acl' && $currentrow['0'] != 'static') { // This is not a well-formed record or is an invalid record type $errorcount++; if ($errorcount <= '50') { $message = str_replace("%rownum%", $rownum + 1, $COLLATE['languages']['selected']['erroronrow']); $message = str_replace("%error%", $COLLATE['languages']['selected']['invalidrecord'], $message); echo "<p>{$message}</p>"; } } $row[$rownum] = $currentrow; $rownum++; } fclose($handle); unset($currentrow); unset($rownum); if ($errorcount === '0') { // don't bother validating data further if we didn't even find a propper csv file $dbo->query("START TRANSACTION"); $recordprocessingorder = array('block', 'subnet', 'acl', 'static'); foreach ($recordprocessingorder as $recordtype) { foreach ($row as $currentrow => $rowdata) { if ($rowdata['0'] === "{$recordtype}") { $result = read_in_csv_row($rowdata); if ($result['error'] === true) { $errorcount++; if ($errorcount <= '50') { $message = str_replace("%rownum%", $currentrow + 1, $COLLATE['languages']['selected']['erroronrow']); $message = str_replace("%error%", $COLLATE['languages']['selected'][$result['errormessage']], $message); echo "<p>{$message}</p>"; } } else { $dbo->query($result['sql']); $sql .= $result['sql'] . ';<br><br>'; #### ---> remove this line later <--- ####### } } } unset($rowdata); } unset($recordtype); if ($errorcount !== '0') { $dbo->query("ROLLBACK"); } else { $dbo->query("COMMIT"); } } if ($errorcount > '50') { echo "<p>" . $COLLATE['languages']['selected']['manyimporterr'] . "</p>"; } if ($errorcount != '0') { echo "<br /><p><a href=\"command.php\">" . $COLLATE['languages']['selected']['tryagain'] . "</a></p>"; } else { // Success! $importedrecords = $currentrow + 1; $successmessage = str_replace("%rows%", $importedrecords, $COLLATE['languages']['selected']['importsuccess']); echo "<p><b>{$successmessage}</b></p>"; $logmessage = "Bulk imported {$importedrecords} records (including blank lines)."; collate_log('5', $logmessage); } include "include/footer.php"; exit; // report errors if any } include "include/footer.php"; exit; }
function delete_block() { global $COLLATE; global $block_id; $dbo = getdbo(); $block_ids = array(); $block_ids[] = $block_id; $sql = "SELECT name FROM blocks WHERE id='{$block_id}'"; $result = $dbo->query($sql); if ($result->rowCount() != '1') { header("HTTP/1.1 400 Bad Request"); echo $COLLATE['languages']['selected']['selectblock']; exit; } $name = $result->fetchColumn(); collate_log("4", "Block {$name} has been deleted!"); if (find_child_blocks($block_id) !== false) { # this is a recursive function $block_ids = array_merge($block_ids, find_child_blocks($block_id)); } foreach ($block_ids as $block_id) { // First delete all static IPs $sql = "DELETE FROM statics WHERE subnet_id IN (SELECT id FROM subnets WHERE block_id='{$block_id}')"; $dbo->query($sql); // Next, remove the DHCP ACLs $sql = "DELETE FROM acl WHERE subnet_id IN (SELECT id FROM subnets WHERE block_id='{$block_id}')"; $dbo->query($sql); // Next, remove the subnets $sql = "DELETE FROM subnets WHERE block_id='{$block_id}'"; $dbo->query($sql); // Lastly, delete the IP block $sql = "DELETE FROM blocks WHERE id='{$block_id}'"; $dbo->query($sql); } # we don't output to the user on success. The row fades on the page to provide feedback. }
function ldap_auth($username, $password) { global $COLLATE; global $dbo; // First make sure that they are a valid application user, then check their password in the Directory. $sql = "SELECT accesslevel, loginattempts FROM users WHERE username='******'"; $row = $dbo->query($sql); if ($row->rowCount() != "1") { return FALSE; } list($accesslevel, $loginattempts) = $row->fetch(PDO::FETCH_NUM); if ($loginattempts >= $COLLATE['settings']['loginattempts']) { return "locked"; } $username = utf8_encode($username); $password = utf8_encode($password); // Find domain if there is one -- If no domain exists, return error if (!strstr($username, "@")) { $username .= "@" . $COLLATE['settings']['domain']; } // Tokenize based on @ sign. Second token is domain name. Look up domain name in database to find ldap server $nothing = strtok($username, "@"); // Dump first token...sloppy don't care right now. $domain = strtok("@"); if (empty($domain)) { $domain = $COLLATE['settings']['domain']; } $sql = "SELECT domain, server FROM `ldap-servers` WHERE domain='{$domain}'"; $result = $dbo->query($sql); if ($result->rowCount() < '1') { return FALSE; } while (list($domain, $ldap_server) = $result->fetch(PDO::FETCH_NUM)) { # do anonymous binds to find a working server // set up ldap connect parameters. Connection doesn't happen until ldap_bind... $ldapconn = ldap_connect($ldap_server); $ldapbind = @ldap_bind($ldapconn); if ($ldapbind) { # good server ldap_unbind($ldapconn); $ldapconn = ldap_connect($ldap_server); $ldapbind = ldap_bind($ldapconn, $username, $password); // verify binding if (!$ldapbind) { $auth = false; } else { $auth = array(); $auth['accesslevel'] = $accesslevel; $auth['passwdexpire'] = '0000-00-00 00:00:00'; } return $auth; } collate_log('5', "Failed to do anonymous bind to LDAP server: {$ldap_server}"); } # If we get here, all servers are down collate_log('5', 'No ldap servers responded to anonymous binds.'); return false; }
function submit_user() { global $COLLATE; global $dbo; include 'include/validation_functions.php'; # validations are organized by all checks that don't require db lookups, then all that do # in the order that the vars are listed below $username = isset($_POST['username']) ? $_POST['username'] : ''; $tmppasswd = isset($_POST['tmppasswd']) && !empty($_POST['tmppasswd']) ? sha1(clean($_POST['tmppasswd'])) : ''; $phone = isset($_POST['phone']) ? $_POST['phone'] : ''; $email = isset($_POST['email']) ? $_POST['email'] : ''; $language = isset($_POST['languages']) ? $_POST['languages'] : ''; $perms = isset($_POST['perms']) && preg_match("/^[012345]{1}\$/", $_POST['perms']) ? $_POST['perms'] : ''; $locked = isset($_POST['locked']) ? 'on' : 'off'; $loginattempts = $locked == 'on' ? '9' : '0'; $ldapexempt = isset($_POST['ldapexempt']) && $_POST['ldapexempt'] == "on" ? true : false; $edit = isset($_GET['edit']) && preg_match("/true|false/", $_GET['edit']) ? true : false; $logged_in_user = isset($COLLATE['user']['username']) ? $COLLATE['user']['username'] : ''; if ($logged_in_user != $username) { AccessControl('5', null); } if ($edit === false) { $return = validate_text($username, 'username'); if ($return['0'] === false) { $notice = $return['error']; header("Location: users.php?op=add&username={$username}&phone={$phone}&email={$email}¬ice={$notice}"); exit; } $action = 'add'; } else { $action = 'edit'; } $return = validate_text($phone, 'phone'); if ($return['0'] === false) { $notice = $return['error']; header("Location: users.php?op={$action}&username={$username}&phone={$phone}&email={$email}¬ice={$notice}"); exit; } $return = validate_text($email, 'email'); if ($return['0'] === false) { $notice = $return['error']; header("Location: users.php?op={$action}&username={$username}&phone={$phone}&email={$email}¬ice={$notice}"); exit; } if (empty($email) && empty($phone)) { $notice = "onecontact"; header("Location: users.php?op={$action}&username={$username}&phone={$phone}&email={$email}¬ice={$notice}"); exit; } foreach (glob("languages/*.php") as $filename) { include $filename; } if (!isset($languages[$language]['isocode']) || $language != $languages[$language]['isocode']) { header("Location: users.php?op={$action}&username={$username}&phone={$phone}&email={$email}¬ice=invalidrequest"); exit; } $test = $dbo->query("SELECT id FROM users WHERE username='******'"); if ($test->rowCount() > "0" && $edit === false) { #duplicate user $notice = "nameconflict-notice"; header("Location: users.php?op=add&username={$username}&phone={$phone}&email={$email}¬ice={$notice}"); exit; } elseif ($test->rowCount() !== 1 && $edit !== false) { #can't edit a user that doesn't exist $notice = "invalidrequest"; header("Location: users.php?op=add&username={$username}&phone={$phone}&email={$email}¬ice={$notice}"); exit; } if ($edit === false) { $sql = "INSERT INTO users (username, tmppasswd, accesslevel, phone, email, loginattempts, ldapexempt, language) \r\n VALUES('{$username}', '{$tmppasswd}', '{$perms}', '{$phone}', '{$email}', '{$loginattempts}', '{$ldapexempt}', '{$language}')"; } else { if ($COLLATE['user']['accesslevel'] == '5' || $COLLATE['settings']['perms'] > '5') { #can update all vars if (empty($tmppasswd)) { $sql = "UPDATE users SET accesslevel='{$perms}', phone='{$phone}', email='{$email}', loginattempts='{$loginattempts}', \r\n\t\t ldapexempt='{$ldapexempt}', language='{$language}' \r\n\t WHERE username='******'"; } else { $sql = "UPDATE users SET tmppasswd='{$tmppasswd}', accesslevel='{$perms}', phone='{$phone}',\r\n\t email='{$email}', loginattempts='{$loginattempts}', ldapexempt='{$ldapexempt}', language='{$language}' \r\n\t WHERE username='******'"; } } else { # can only update basic info $sql = "UPDATE users SET username='******', phone='{$phone}', email='{$email}', language='{$language}' \r\n\t WHERE username='******'"; } } if ($edit === false) { $message = "User added: {$username}"; $notice = "useradded-notice"; } else { $message = "User updated: {$username}"; $notice = "userupdated-notice"; } collate_log('5', $message); // adds and modifications are always logged $dbo->query($sql); header("Location: users.php?op=edit&username={$username}¬ice={$notice}"); exit; }