# # For further information on Open-AudIT or for a license other than AGPL please see # www.opmantek.com or email contact@opmantek.com # # ***************************************************************************** * * PHP version 5.3.3 * * @category Helper * @author Mark Unwin * @copyright 2014 Opmantek * @license http://www.gnu.org/licenses/agpl-3.0.html aGPL v3 * @version GIT: Open-AudIT_3.5.2 * @link http://www.open-audit.org */ if ( ! function_exists('response_create')) { /** * [response_create description] * @return [type] [description] */ function response_create() { error_reporting(E_ALL); $instance = & get_instance(); $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_create'; $log->status = 'creating response object'; $log->summary = ''; $instance->load->model('m_roles'); $instance->roles = $instance->m_roles->collection(1); $instance->load->model('m_users'); // Define our constans for use in htmlspecialchars if ( ! defined('CHARSET')) { define('CHARSET', 'UTF-8'); if (phpversion() >= 5.4) { define('REPLACE_FLAGS', ENT_COMPAT | ENT_XHTML); } else { define('REPLACE_FLAGS', ENT_COMPAT); } } // make sure we have the required header if (empty($_SERVER['HTTP_ACCEPT'])) { $_SERVER['HTTP_ACCEPT'] = ''; } // enable the $_GET global parse_str(substr(strrchr($_SERVER['REQUEST_URI'], '?'), 1), $_GET); $response = new stdClass(); $response->meta = new stdClass(); $response->links = new stdClass(); $response->included = array(); $response->logs = array(); $response->meta->access_token = @$instance->access_token; $response->meta->action = ''; $response->meta->baseurl = ''; if ( ! empty($instance->config->config['base_url'])) { $response->meta->baseurl = $instance->config->config['base_url']; } if ( ! empty($instance->config->config['id'])) { $response->meta->cloud_id = $instance->config->config['id']; } $response->meta->collection = ''; $response->meta->current = 'y'; $response->meta->debug = false; $response->meta->debug = true; $response->meta->filtered = ''; $response->meta->format = ''; $response->meta->groupby = ''; $response->meta->header = 'HTTP/1.1 200 OK'; $response->meta->id = null; // $response->meta->ids = null; // Only set below if it contains data $response->meta->include = ''; $response->meta->limit = ''; $response->meta->offset = 0; $response->meta->properties = ''; // NOTE see response_get_query_filter for why we do the below with the query string $response->meta->query_string = urldecode($_SERVER['QUERY_STRING']); $response->meta->query_string = str_replace('&', '&', $response->meta->query_string); $response->meta->request_method = strtoupper($instance->input->server('REQUEST_METHOD')); $response->meta->requestor = ''; if ( ! empty($_SERVER['HTTP_REQUESTOR'])) { $response->meta->requestor = (string)$_SERVER['HTTP_REQUESTOR']; } $response->meta->sort = ''; $response->meta->sub_resource = ''; // $response->meta->sub_resource_id = 0; // Only set below if it contains data if ( ! empty($GLOBALS['timer_start'])) { $response->meta->time_start = $GLOBALS['timer_start']; } else { $response->meta->time_start = microtime(true); } $response->meta->time_end = 0; $response->meta->time_elapsed = 0; $response->meta->total = 0; $response->meta->timestamp = $instance->config->config['timestamp']; $response->meta->timezone = $instance->config->config['timezone']; $response->meta->version = 1; $response->meta->filter = array(); $response->meta->internal = new stdClass(); $response->meta->query_parameters = array(); $response->meta->received_data = array(); $response->meta->sql = array(); // Need to set vesrion FIRST because it may impact routes $response->meta->version = response_get_version($instance->uri->segments, $instance->input->get_request_header('Accept')); // Refactor the uri->segments to remove /api/1 or /v1, /v2, etc $instance->uri->segments = response_set_uri($instance->uri->segments); // no dependencies - set in GET or POST $response->meta->debug = response_get_debug($instance->input->get('debug'), $instance->input->post('debug'), $instance->input->get_request_header('debug')); // no dependencies - set in GET or POST or HEADERS $response->meta->format = response_get_format($instance->input->get('format'), $instance->input->post('format'), $instance->input->get_request_header('Accept')); // no dependencies - set in GET or POST or HEADERS $response->meta->current = response_get_current($instance->input->get('current'), $instance->input->post('current')); // depends on version affecting URI - set in URI or POST $response->meta->collection = response_get_collection($instance->uri->segment(1)); // Set the heading based on the collection $response->meta->heading = ucfirst($response->meta->collection); // depends on version affecting URI, collection, request_method, format if ($response->meta->collection === 'search' && $response->meta->request_method !== 'POST') { // Redirect as we only accept POSTs for /search log_error('ERR-0007', 'search:' . $response->meta->request_method); if ($response->meta->format !== 'screen') { $response->errors = array(); return($response); } else { $instance->session->set_flashdata('error', $response->errors[0]->detail); redirect('devices'); exit(); } } $instance->user->org_list = response_get_org_list($response->meta->collection, $instance->user); // depends on version affecting URI, collection - set in URI or POST $response->meta->id = response_get_id(html_entity_decode(urldecode($instance->uri->segment(2))), $response->meta->collection, $instance->user->org_list); // no dependencies - set in GET or POST $temp = response_get_ids($instance->input->get('ids'), $instance->input->post('ids')); // Only set if not empty if ( ! empty($temp)) { $response->meta->ids = $temp; } // no dependencies - set in PATCH or POST, can set ID $response->meta->received_data = response_get_data($response->meta->request_method); if ( ! empty($response->meta->received_data->id)) { if ($response->meta->collection !== 'database' && $response->meta->collection !== 'configuration') { $response->meta->id = intval($response->meta->received_data->id); } } // depends on version affecting URI, collection and format $response->meta->sub_resource = response_get_sub_resource($instance->input->get('sub_resource'), $instance->input->post('sub_resource'), $instance->uri->segment(3, ''), $response->meta->collection, $response->meta->format); // depends on version affecting URI, sub_resource $temp = response_get_sub_resource_id($response->meta->sub_resource, intval((string)urldecode($instance->uri->segment(4, ''))), $instance->input->get('ids'), $instance->input->post('ids')); if ( ! empty($temp)) { $response->meta->sub_resource_id = $temp; } // depends on id, ids, recevied_data, request_method, sub_resource and sub_resource_id $response->meta->action = response_get_action($response); // If we're creating data (POST), we should have an access token (configuration depending) if ( ! empty($response->meta->received_data)) { if ($response->meta->request_method === 'POST' && ! empty($CI->config->config['access_token_enable']) && $CI->config->config['access_token_enable'] === 'y') { if (empty($CI->response->meta->received_data->access_token)) { log_error('ERR-0034', $response->meta->collection . ':' . $response->meta->action); $instance->session->set_flashdata('error', $response->errors[0]->detail); if ($response->meta->format !== 'screen') { output(); exit(); } else { redirect($response->meta->collection); exit(); } } else if ( ! in_array($response->meta->received_data->access_token, $instance->user->access_token)) { log_error('ERR-0035', $response->meta->collection . ':' . $response->meta->action); $instance->session->set_flashdata('error', $response->errors[0]->detail); if ($response->meta->format !== 'screen') { output(); exit(); } else { redirect($response->meta->collection); exit(); } } } } // depends on action if ($response->meta->action === 'create' OR $response->meta->action === 'import') { $response->meta->header = 'HTTP/1.1 201 Created'; } // depends on collection and format $response->meta->include = response_get_include($instance->input->get('include'), $instance->input->post('include'), $response->meta->collection, $response->meta->format); // depends on version affecting URI, collection $response->meta->sort = response_get_sort($response->meta->collection); $response->meta->internal->sort = ''; if ($response->meta->sort !== '') { $response->meta->internal->sort = 'ORDER BY ' . $response->meta->sort; } // depends on version affecting URI, collection $response->meta->groupby = response_get_groupby($instance->input->get('groupby'), $instance->input->post('groupby'), $response->meta->collection); $response->meta->internal->groupby = ''; if ($response->meta->groupby) { $response->meta->internal->groupby = 'GROUP BY ' . $response->meta->groupby; } // no dependencies - set in GET or POST $response->meta->offset = response_get_offset(); // depends on format - set in GET or POST $response->meta->limit = response_get_limit($instance->input->get('limit'), $instance->input->post('limit'), $response->meta->format, @$instance->config->config['page_size']); // depends on offset $response->meta->internal->limit = ''; if ( ! empty($response->meta->limit)) { $response->meta->internal->limit = 'LIMIT ' . intval($response->meta->offset) . ',' . intval($response->meta->limit); } // depends on collection $response->meta->properties = response_get_properties($response->meta->collection, $response->meta->action, $response->meta->sub_resource); // depends on properties, collection, sub_resource $response->meta->internal->properties = response_get_internal_properties($response->meta->properties, $response->meta->collection, $response->meta->sub_resource); // depends on query string $response->meta->filter = response_get_query_filter($response->meta->query_string, 'filter'); // depends on query string $response->meta->query_parameters = response_get_query_filter($response->meta->query_string, 'query'); // depends on filter // $response->meta->query_parameters = $response->meta->filter; $response->meta->internal->filter = response_get_internal_filter($response->meta->filter, $response->meta->collection); if ($response->meta->collection === 'devices') { $response->meta->internal->join = response_get_internal_join($response->meta->filter, $response->meta->collection); } $response->links = response_get_links($response->meta->collection, $response->meta->id, $response->meta->sub_resource, @$response->meta->sub_resource_id); $permission = response_get_permission_ca($instance->user, $response->meta->collection, $response->meta->action, $response->meta->received_data, $response->meta->id); if ( ! $permission) { if ($response->meta->format === 'json') { echo json_encode($response); exit; } else { $instance->session->set_flashdata('error', 'Permission denied for collection / action.'); redirect($response->meta->collection); } redirect('/'); } $permission = response_get_permission_id($instance->user, $response->meta->collection, $response->meta->action, $response->meta->received_data, $response->meta->id); if ( ! $permission) { if ($response->meta->format === 'json') { echo json_encode($response); exit; } else { $instance->session->set_flashdata('error', 'Permission denied for OrgID.'); redirect($response->meta->collection); } redirect('/'); } if ( ! empty($instance->response->logs)) { $response->logs = $instance->response->logs; } return $response; } } if ( ! function_exists('response_get_action')) { /** * Determine the requested action * @param object $response Our response object * @return string The action */ function response_get_action($response) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_action'; $log->status = 'parsing'; $log->summary = 'get action'; $instance = & get_instance(); $collection = $response->meta->collection; $id = $response->meta->id; // NOTE - devices IDs may or may not be set. We only test for ! empty, so @ is fine. $device_ids = @$response->meta->ids; $received_data = $response->meta->received_data; $request_method = $response->meta->request_method; $sub_resource = $response->meta->sub_resource; // NOTE - sub_resource_id may or may not be set. We only test for ! empty, so @ is fine. $sub_resource_id = @$response->meta->sub_resource_id; $action = ''; $valid_actions = response_valid_actions(); if (in_array($instance->uri->segment(2), $valid_actions)) { $action = $instance->uri->segment(2); } if (empty($action) && in_array($instance->uri->segment(3), $valid_actions)) { $action = $instance->uri->segment(3); } if (isset($_GET['action']) && in_array($_GET['action'], $valid_actions)) { $action = $_GET['action']; $log->summary = 'Set collection according to GET.'; } if (isset($_POST['action']) && in_array($_POST['action'], $valid_actions)) { $action = $_POST['action']; $log->summary = 'Set collection according to POST.'; } if ($request_method === 'GET' && empty($id) && $action === '') { $action = 'collection'; $log->summary = 'Set action because GET, no id, no action.'; } if ($request_method === 'GET' && empty($id) && $action === 'reset') { $action = 'reset'; $log->summary = 'Set action because GET, action = reset.'; } if ($request_method === 'GET' && empty($id) && $action === 'create') { $action = 'create_form'; $log->summary = 'Set action because GET, no id and action = create.'; } if ($request_method === 'GET' && $action === 'create' && ! empty($sub_resource) && empty($sub_resource_id)) { $action = 'sub_resource_create_form'; $log->summary = 'Set action because GET, sub_resource, no sub_resource_id and action = create.'; } if ($request_method === 'GET' && $action === 'sub_resource_read' && ! empty($sub_resource)) { $action = 'sub_resource_read'; $log->summary = 'Set action because GET, sub_resource and action = sub_resource_read.'; } if ($request_method === 'GET' && $action === 'download' && $sub_resource !== '' && ! empty($sub_resource_id)) { $action = 'sub_resource_download'; $log->summary = 'Set action because GET, sub_resource, sub_resource_id and action = download.'; } if ($request_method === 'GET' && $action === 'import' && empty($id)) { $action = 'import_form'; $log->summary = 'Set action because GET, no id and action = import.'; } if ($request_method === 'GET' && $action === '' && ! empty($id)) { $action = 'read'; $log->summary = 'Set action because GET, id and no action.'; } if ($request_method === 'GET' && $action === 'test' && ! empty($id)) { $action = 'test'; $log->summary = 'Set action because GET, id and action = test.'; } if ($action === 'update' && $collection === 'database') { // Special case for the database endpoint $action = 'update'; $log->summary = 'Set action because collection = database and action = update.'; } if ($request_method === 'GET' && $action === 'execute' && $collection === 'database' && ! empty($sub_resource)) { $action = 'execute'; $log->summary = 'Set action because GET, collection = database and action = execute'; } if ($request_method === 'GET' && $action === 'execute' && ! empty($id)) { $action = 'execute'; $log->summary = 'Set action because GET, id and action = execute'; } if ($request_method === 'GET' && $action === 'update' && empty($id) && ! empty($device_ids)) { $action = 'bulk_update_form'; $log->summary = 'Set action because GET, ids, no id and action = update.'; } if ($request_method === 'GET' && $action === 'download' && ! empty($id) && empty($sub_resource)) { $action = 'download'; $log->summary = 'Set action because GET, id and action = download.'; } if ($request_method === 'POST' && $action === '' && empty($id) && ! empty($received_data)) { $action = 'create'; $log->summary = 'Set action because POST, data, no id and no action.'; } if ($request_method === 'POST' && $action === '' && empty($id) && empty($received_data)) { $action = 'collection'; $log->summary = 'Set action because POST, no id, no data and no action.'; } if ($request_method === 'POST' && $action === 'import' && empty($id)) { $action = 'import'; $log->summary = 'Set action because POST, no id and action = import.'; } if ($request_method === 'POST' && $action === 'update' && empty($id) && ! empty($device_ids)) { $action = 'update'; $log->summary = 'Set action because POST, ids, no id and action = update.'; } if ($request_method === 'POST' && $action === 'update' && empty($id) && $collection === 'database') { $action = 'update'; $log->summary = 'Set action because POST, no id, collection is database and action = update.'; } if (($request_method === 'PUT' OR $request_method === 'PATCH') && $action === '' && ! empty($id)) { $action = 'update'; $log->summary = 'Set action because PATCH/PUT, id and no action.'; } if ($request_method === 'PATCH' && ! empty($device_ids)) { $action = 'update'; $log->summary = 'Set action because PATCH, ids and no id.'; } if ($request_method === 'POST' && ( ! empty($id) OR ! empty($device_ids)) && ! empty($sub_resource)) { $action = 'sub_resource_create'; $log->summary = 'Set action because POST, id, sub_resource.'; } if ($request_method === 'DELETE' && ! empty($id) && empty($sub_resource)) { $action = 'delete'; $log->summary = 'Set action because DELETE, id.'; } if ($request_method === 'DELETE' && ! empty($id) && ! empty($sub_resource) && ! empty($sub_resource_id)) { $action = 'sub_resource_delete'; $log->summary = 'Set action because DELETE, id, sub_resource, sub_resource_id.'; } if ($action === '') { $action = 'collection'; $log->summary = 'Set action because no action.'; } if ( ! in_array($action, $valid_actions)) { $action = 'collection'; $log->summary = 'Set action because not in allowed action list.'; } if ($action !== '') { $log->detail = 'ACTION: ' . $action; stdlog($log); } return $action; } } if ( ! function_exists('response_get_collection')) { /** * Determine and validate the requested collection * @param string $collection The requested collection * @return string The validated collection */ function response_get_collection($collection = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_collection'; $log->status = 'parsing'; $log->summary = 'get data'; $collections = response_valid_collections(); if ( ! empty($collection)) { if (in_array($collection, $collections)) { $log->summary = 'Set collection according to GET.'; } else { $log->summary = 'Collection set to summaries as invalid collection supplied.'; $log->summary = 5; $collection = 'summaries'; } } else { $log->summary = 'Collection set to summaries as no collection supplied.'; $log->summary = 5; $collection = 'summaries'; } if ( ! empty($collection)) { $log->detail = 'COLLECTION: ' . $collection; stdlog($log); } return $collection; } } if ( ! function_exists('response_get_current')) { /** * Return the current ettribute derived from the HEADERS or URL (get) or BODY (post) * @return string The response format requested */ function response_get_current($get = '', $post = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_current'; $log->status = 'parsing'; $log->summary = 'get current'; $current = 'y'; $log->summary = 'Set current to default.'; if ( ! empty($get)) { $current = $get; $log->summary = 'Set current according to GET.'; } if ( ! empty($post)) { $current = $post; $log->summary = 'Set current according to POST.'; } $valid_current = response_valid_current(); if ( ! in_array($current, $valid_current)) { $log->summary = 'Set current to y, because unknown current: ' . $current; $log->status = 'warning'; $current = 'y'; } $log->detail = 'CURRENT: ' . $current; stdlog($log); return $current; } } if ( ! function_exists('response_get_data')) { /** * Parse $_POST and $_PATCH for sent data * @param string $request_method How we got this data * @return array The received data */ function response_get_data($request_method = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_data'; $log->status = 'parsing'; $log->summary = 'get data'; $data_supplied_by = ''; $received_data = array(); if ($request_method === 'POST') { if ( ! empty($_POST['data']) && is_array($_POST['data'])) { $log->summary = 'Set received data according to POST (form).'; $received_data = $_POST['data']; $received_data = json_encode($received_data); $received_data = json_decode($received_data); $log->detail = 'Data has been supplied via POST HTML form.'; $data_supplied_by = 'form'; } else if ( ! empty($_POST['data'])) { $log->summary = 'Set received data according to POST (json).'; // This is straight JSON submitted data in a string $received_data = @json_decode($_POST['data']); $log->detail = 'Data has been supplied via POST json.'; $data_supplied_by = 'json'; } } if ($request_method === 'PATCH') { $data_json = urldecode(str_replace('data=', '', file_get_contents('php://input'))); $data_object = json_decode($data_json); $options = @$data_object->data->attributes->options; if (empty($data_object)) { // } else { $log->summary = 'Set received data according to PATCH.'; $received_data = new stdClass(); if ( ! empty($data_object->data)) { $received_data = $data_object->data; } else { $received_data = $data_object; } if ( ! empty($options)) { $received_data->attributes->options = $options; } } } if ( ! empty($received_data)) { $log->detail = 'RECEIVED DATA: ' . json_encode($received_data); stdlog($log); } return $received_data; } } if ( ! function_exists('response_get_debug')) { /** * Determine if the request uses debug * @return bool */ function response_get_debug($get = '', $post = '', $header = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_debug'; $log->status = 'parsing'; $log->summary = 'get debug'; $instance = & get_instance(); $debug = false; $instance->output->enable_profiler(false); if ( ! empty($get) && strtolower($get) === 'true') { $log->summary = 'Set debug according to GET.'; $log->detail = 'DEBUG: true'; $instance->output->enable_profiler(true); $debug = true; stdlog($log); } if ( ! empty($post) && strtolower($post) === 'true') { $log->summary = 'Set debug according to POST.'; $log->detail = 'DEBUG: true'; $instance->output->enable_profiler(true); $debug = true; stdlog($log); } if ( ! empty($header) && strtolower($header) === 'true') { $log->summary = 'Set debug according to HEADER.'; $log->detail = 'DEBUG: true'; $instance->output->enable_profiler(true); $debug = true; stdlog($log); } return $debug; } } if ( ! function_exists('response_get_filter')) { /** * [response_get_filter description] * @param [type] $query_string [description] * @return [type] [description] */ function response_get_query_filter($query_string, $type = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_filter'; $log->status = 'parsing'; $log->summary = 'get filter'; $instance = & get_instance(); $reserved_words = response_valid_reserved_words(); $filter = array(); // NOTE - Had to create our own parsing routine because PHP replaces .'s with underscores // in incoming variable names. The unfortunate result is that we can not use a . in // a variable value when using GET (so no system.manufacturer=Dell, for example) // PHP Bug Report - https://bugs.php.net/bug.php?id=45272 // PHP Docs - https://php.net/manual/en/language.variables.external.php if (empty($query_string)) { return array(); } if ( ! empty($query_string)) { foreach (explode('&', $query_string) as $item) { $query = new stdClass(); $query->name = substr($item, 0, strpos($item, '=')); $query->operator = '='; $query->value = str_replace($query->name.'=', '', $item); if (strtolower(substr($query->value, 0, 8)) === 'not like') { $query->value = '%' . substr($query->value, 8) . '%'; $query->operator = 'not like'; // $query->value = str_replace('"', '\"', $query->value); $query->value = mysqli_real_escape_string($instance->db->conn_id, $query->value); } if (strtolower(substr($query->value, 0, 5)) === '!like') { $query->value = '%' . substr($query->value, 5) . '%'; $query->operator = 'not like'; // $query->value = str_replace('"', '\"', $query->value); $query->value = mysqli_real_escape_string($instance->db->conn_id, $query->value); } $operator = substr($query->value, 0, 4); if (strtolower($operator) === 'like') { $query->value = '%' . substr($query->value, 4) . '%'; $query->operator = $operator; // $query->value = str_replace('"', '\"', $query->value); $query->value = mysqli_real_escape_string($instance->db->conn_id, $query->value); } if (substr($query->value, 0, 3) === 'in(' && strpos($query->value, ')') === strlen($query->value)-1) { // Removed the below. It is up to the user to quote enclose strings if required // If we do this for them, they end up double quoted upon link generation in output_helper // $temp_value = substr($query->value, 3, strlen($query->value)-4); // $temp_value = str_replace("'", "\'", $temp_value); // $temp_value = str_replace(",", "','", $temp_value); // $query->value = "('" . $temp_value . "')"; $query->value = substr($query->value, 2); $query->operator = 'in'; if (strpos($query->value, '"') !== false OR strpos($query->value, "'") !== false) { $query->value = trim($query->value, '()'); $temp = explode(',', $query->value); $query->value = '('; foreach ($temp as $value) { $value = trim($value); $value = trim($value, '"\' '); // $value = str_replace('\"', '"', $value); // $value = str_replace('"', '\"', $value); $value = mysqli_real_escape_string($instance->db->conn_id, $value); $query->value .= '"' . $value . '",'; } $query->value = trim($query->value, ','); $query->value .= ')'; } } if (substr($query->value, 0, 6) === 'notin(' && strpos($query->value, ')') === strlen($query->value)-1) { $query->value = substr($query->value, 5); $query->operator = 'not in'; if (strpos($query->value, '"') !== false OR strpos($query->value, "'") !== false) { $query->value = trim($query->value, '()'); $temp = explode(',', $query->value); $query->value = '('; foreach ($temp as $value) { $value = trim($value); $value = trim($value, '"\' '); // $value = str_replace('\"', '"', $value); // $value = str_replace('"', '\"', $value); $value = mysqli_real_escape_string($instance->db->conn_id, $value); $query->value .= '"' . $value . '",'; } $query->value = trim($query->value, ','); $query->value .= ')'; } } $operator = substr($query->value, 0, 2); if ($operator === '!=' OR $operator === '>=' OR $operator === '<=') { $query->value = substr($query->value, 2); $query->operator = $operator; // $query->value = str_replace('"', '\"', $query->value); $query->value = mysqli_real_escape_string($instance->db->conn_id, $query->value); } $operator = substr($query->value, 0, 1); if ($operator === '=' OR $operator === '>' OR $operator === '<') { $query->value = substr($query->value, 1); $query->operator = $operator; // $query->value = str_replace('"', '\"', $query->value); $query->value = mysqli_real_escape_string($instance->db->conn_id, $query->value); } $query->name = preg_replace('/[^A-Za-z0-9\.\_]/', '', $query->name); if ($query->value === false) { $query->value = ''; } // Accept first_seen, last_seen, edited_date and timestamp as numeric unix_timestamp's and convert them to a local timestamp string $item = substr($query->name, strpos($query->name, '.')+1); if (($item === 'first_seen' OR $item === 'last_seen' OR $item === 'when' OR $item === 'edited_date' OR $item === 'timestamp') && is_numeric($query->value)) { if ($query->operator === 'like' OR $query->operator === 'not like') { $query->value = str_replace('%', '', $query->value); } $query->value = from_unix_timestamp($query->value); if ($query->operator === 'like' OR $query->operator === 'not like') { $query->value = '%' . $query->value . '%'; } } if (empty($query->operator)) { $query->operator = '='; } if ( ! empty($query->name) && ! in_array($query->name, $reserved_words) && $type === 'filter') { $filter[] = $query; } if ($type === 'query') { $filter[] = $query; } } } if ( ! empty($filter)) { $log->detail = strtoupper($type) .': ' . json_encode($filter); stdlog($log); } return $filter; } } if ( ! function_exists('response_get_format')) { /** * Return the response format derived from the HEADERS or URL (get) or BODY (post) * @return string The response format requested */ function response_get_format($get = '', $post = '', $header = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_format'; $log->status = 'parsing'; $log->summary = 'get version'; $format = 'json'; if (strpos($header, 'application/json') !== false) { $format = 'json'; $log->summary = 'Set format according to HEADERS.'; } if (strpos($header, 'html') !== false) { $format = 'screen'; $log->summary = 'Set format according to HEADERS.'; } if ( ! empty($get)) { $format = $get; $log->summary = 'Set format according to GET.'; } if ( ! empty($post)) { $format = $post; $log->summary = 'Set format according to POST.'; } $valid_formats = response_valid_formats(); if ( ! in_array($format, $valid_formats)) { $log->summary = 'Set format to json, because unknown format: ' . $format; $log->status = 'warning'; $format = 'json'; } $log->detail = 'FORMAT: ' . $format; stdlog($log); return $format; } } if ( ! function_exists('response_get_groupby')) { /** * Determine and validate the requested groupby * @param string $collection The request collection * @return string The validated groupby */ function response_get_groupby($get = '', $post = '', $collection = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_groupby'; $log->status = 'parsing'; $log->summary = 'get action'; $instance = & get_instance(); $groupby = ''; if ( ! empty($get)) { $groupby = $get; $log->summary = 'Set groupby according to GET.'; } if ( ! empty($post)) { $groupby = $post; $log->summary = 'Set groupby according to POST.'; } if ( ! empty($groupby)) { if (strpos($groupby, '.') !== false) { $temp = explode('.', $groupby); if ( ! $instance->db->field_exists($temp[1], $temp[0])) { $groupby = ''; $log->detail = "Invalid groupby supplied ({$groupby}), removed."; stdlog($log); } else { $groupby = $temp[0] . '.' . $temp[1]; } } else { $temp = $collection; if ($temp === 'devices') { $temp = 'system'; } if ( ! $instance->db->field_exists($groupby, $temp)) { $groupby = ''; $log->detail = "Invalid groupby supplied ({$groupby}), removed."; stdlog($log); } else { $groupby = $temp . '.' . $groupby; } } } if ($groupby !== '') { $log->detail = 'GROUPBY: ' . $groupby; stdlog($log); } return $groupby; } } if ( ! function_exists('response_get_id')) { /** * Determine if we are passed an ID or a name and return an integer ID * @param string $id [description] * @param string $collection [description] * @param string $org_list [description] * @return int|null */ function response_get_id($id = '', $collection = '', $org_list = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_id'; $log->status = 'parsing'; $log->summary = 'get id'; $instance = & get_instance(); if (empty($id)) { $log->summary = 'No ID provided, returning NULL.'; $log->detail = 'ID: null'; stdlog($log); return null; } if (is_numeric($id)) { // we have a number, return that $log->summary = 'Number ID provided, returning integer.'; $log->detail = 'ID: ' . intval($id); stdlog($log); return intval($id); } else { $actions = response_valid_actions(); $collections = response_valid_collections(); $no_org_id = array('chart', 'configuration', 'database', 'errors', 'help', 'logs', 'nmis', 'reports', 'roles', 'search', 'sessions'); if ( ! in_array($id, $actions)) { // Our 'id' is a string, but not an action - therefore it's a name if ($collection === 'database') { $instance = & get_instance(); $tables = $instance->db->list_tables(); // add an entry for devices collection <-> system table $tables[] = 'devices'; if ( ! in_array($id, $tables)) { $id = null; } } else if ($collection === 'configuration') { $sql = '/* response_helper::response_get_id */ ' . "SELECT id FROM `configuration` WHERE name = ? ORDER BY id DESC LIMIT 1"; $data = array($id); $query = $instance->db->query($sql, $data); $result = $query->result(); if ( ! empty($result)) { $log->summary = 'ID to Name match in configuration'; $id = intval($result[0]->id); } } else if ($collection === 'devices') { // devices -> system table $sql = '/* response_helper::response_get_id */ ' . "SELECT id FROM system WHERE name LIKE ? AND org_id IN ({$org_list}) ORDER BY id DESC LIMIT 1"; $data = array($id); $query = $instance->db->query($sql, $data); $result = $query->result(); if ( ! empty($result)) { $log->summary = 'ID to Name match in devices'; $id = intval($result[0]->id); } } else if ($collection === 'users') { // Special case the username as we may be given user.name@domain.com for LDAP user, but we only use user.name in users.name $sql = '/* response_helper::response_get_id */ ' . "SELECT id FROM users WHERE name LIKE ? AND org_id IN ({$org_list}) ORDER BY id DESC LIMIT 1"; $temp = explode('@', $id); $data = array($temp[0]); unset($temp); $query = $instance->db->query($sql, $data); $result = $query->result(); if ( ! empty($result)) { $log->summary = 'ID to Name match in users'; $id = intval($result[0]->id); } } else if ($collection === 'orgs') { // orgs.id, not *.org_id $sql = '/* response_helper::response_get_id */ ' . "SELECT id FROM orgs WHERE name LIKE ? AND id IN ({$org_list}) ORDER BY id DESC LIMIT 1"; $data = array($id); $query = $instance->db->query($sql, $data); $result = $query->result(); if ( ! empty($result)) { $log->summary = 'ID to Name match in orgs'; $id = intval($result[0]->id); } } else if ($collection === 'baselines_policies') { // baselines_policies.baseline_id -> baselines.id -> baselines.org_id $sql = '/* response_helper::response_get_id */ ' . "SELECT baselines_policies.id FROM baselines_policies LEFT JOIN baselines ON (baselines_policies.baseline_id = baselines.id) WHERE baselines_policies.name LIKE ? AND baselines.org_id IN ({$org_list}) ORDER BY id DESC LIMIT 1"; $data = array($id); $query = $instance->db->query($sql, $data); $result = $query->result(); if ( ! empty($result)) { $log->summary = 'ID to Name match in baselines_policies'; $id = intval($result[0]->id); } } else if (in_array($collection, $no_org_id)) { $id = 1; } else if (in_array($collection, $collections)) { $sql = '/* response_helper::response_get_id */ ' . "SELECT id FROM {$collection} WHERE name LIKE ? AND org_id IN ({$org_list}) ORDER BY id DESC LIMIT 1"; $data = array($id); $query = $instance->db->query($sql, $data); $result = $query->result(); if ( ! empty($result)) { $log->summary = 'ID to Name match in ' . $collection; $id = intval($result[0]->id); } } if ( ! empty($id)) { $log->detail = 'ID: ' . $id; stdlog($log); } return $id; } } } } if ( ! function_exists('response_get_ids')) { /** * Determine the list of device IDs * @return string The comma separated list of device IDs */ function response_get_ids($get = '', $post = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_ids'; $log->status = 'parsing'; $log->summary = 'get ids'; $device_ids = ''; if ( ! empty($get)) { $device_ids = $get; $log->summary = 'Set IDs according to GET.'; } if ( ! empty($post)) { $device_ids = $post; $log->summary = 'Set IDs according to POST.'; } if ($device_ids !== '') { // Remove a trailing comma if we have one if (substr($device_ids, -1) === ',') { $device_ids = substr($device_ids, 0, -1); } // Set all values to int's $temp = explode(',', $device_ids); for ($i=0; $i < count($temp); $i++) { $temp[$i] = intval($temp[$i]); } // Join by comma's $device_ids = implode(',', $temp); unset($temp); $log->detail = 'IDS: ' . $device_ids; stdlog($log); } return $device_ids; } } if ( ! function_exists('response_get_include')) { /** * Determine the requested included sub-collections * @param string $collection [description] * @param string $format [description] * @return string The requested includes, or all valid includes, or none */ function response_get_include($get = '', $post = '', $collection = '', $format = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_include'; $log->status = 'parsing'; $log->summary = 'get include'; $include = ''; // We only use include for devices. if ($collection !== 'devices') { return $include; } if ( ! empty($get)) { $include = $get; $log->summary = 'Set include according to GET. '; } if ( ! empty($post)) { $include = $post; $log->sumary = 'Set include according to POST. '; } $valid_includes = response_valid_includes(); if (($format === 'screen' && empty($include)) OR $include === '*' OR $include === 'all') { $include = implode(',', $valid_includes); } else { if ( ! empty($include)) { $temp = explode(',', $include); for ($i=0; $i < count($temp); $i++) { if ( ! in_array($temp[$i], $valid_includes)) { unset($temp[$i]); } } $include = implode(',', $temp); } } if ($include !== '') { $log->detail = "INCLUDE: {$include}"; stdlog($log); } return $include; } } if ( ! function_exists('response_get_internal_filter')) { /** * [response_get_internal_filter description] * @param [type] $filter [description] * @param [type] $collection [description] * @return [type] [description] */ function response_get_internal_filter($filter, $collection) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_internal_filter'; $log->status = 'parsing'; $log->summary = 'get internal filter'; $instance = & get_instance(); $reserved_words = response_valid_reserved_words(); $internal_filter = ''; foreach ($filter as $item) { if ( ! in_array($item->name, $reserved_words)) { // We MUST have a name like 'connections.name', not just 'name' if (strpos($item->name, '.') !== false) { if ($item->operator === 'in') { $internal_filter .= ' AND ' . $item->name . ' in ' . $item->value; } else if ($item->operator === 'not in') { $internal_filter .= ' AND ' . $item->name . ' not in ' . $item->value; } else { $internal_filter .= ' AND ' . $item->name . ' ' . $item->operator . ' ' . '"' . $item->value . '"'; } } } } if ($collection !== 'configuration' && $collection !== 'logs' ) { if (is_string($instance->user->org_list)) { $org_list = $instance->user->org_list; } else { $org_list = implode(',', $instance->user->org_list); } if ($internal_filter !== '') { $internal_filter = substr($internal_filter, 5); $internal_filter = ' WHERE orgs.id IN (' . $org_list . ') AND ' . $internal_filter; } else { $internal_filter = ' WHERE orgs.id IN (' . $org_list . ')'; } } if ($collection === 'configuration' OR $collection === 'logs' ) { if ($internal_filter !== '') { $internal_filter = ' WHERE ' . substr($internal_filter, 4); } else { $internal_filter = ''; } } if ($internal_filter !== '') { $log->detail = 'INTERNAL FILTER: ' . json_encode($internal_filter); stdlog($log); } return $internal_filter; } } if ( ! function_exists('response_get_internal_join')) { /** * [response_get_internal_join description] * @param [type] $filter [description] * @param [type] $collection [description] * @return [type] [description] */ function response_get_internal_join($filter, $collection) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_internal_join'; $log->status = 'parsing'; $log->summary = 'get internal_properties'; $join = ''; if ($collection === 'devices') { $valid_sub_resources = response_valid_sub_resources(); $used_sub_resources = array(); if ( ! empty($filter) && is_array($filter) && count($filter) > 0) { foreach ($filter as $item) { if (strpos($item->name, '.') !== false) { $table = substr($item->name, 0, strpos($item->name, '.')); if (in_array($table, $valid_sub_resources) && ! in_array($table, $used_sub_resources)) { $join .= ' LEFT JOIN `' . $table . '` ON (system.id = `' . $table . '`.system_id) '; } $used_sub_resources[] = $table; } } } } if ($join !== '') { $log->detail = 'JOIN: ' . $join; stdlog($log); } return $join; } } if ( ! function_exists('response_get_internal_properties')) { /** * [response_get_internal_properties description] * @param string $properties [description] * @param string $collection [description] * @param string $sub_resource [description] * @return [type] [description] */ function response_get_internal_properties($properties = '', $collection = '', $sub_resource = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_internal_properties'; $log->status = 'parsing'; $log->summary = 'get internal_properties'; $internal_properties = ''; // create our internal properties list - this is what gets executed in SQL if ($properties !== '*' && $properties !== $sub_resource . '.*' && $properties !== '') { $temp = explode(',', $properties); foreach ($temp as $property) { if ($property === 'count' && $collection !== 'chart') { $internal_properties .= 'count(*) as `count`,'; } elseif ($property === 'system_id') { $internal_properties .= 'system.id as `system_id`,'; } else { $internal_properties .= $property . ' AS `' . trim($property) . '`,'; } } $internal_properties = substr($internal_properties, 0, -1); } else { $internal_properties = $properties; } if ($properties === '*' or $properties === '.*') { $temp = $collection; if ($temp === 'devices') { $temp = 'system'; } // Uncomment the below to enable fully qualified column names. // NOTE - this would break the current HTML templates and change the API response. // Maybe enable for v4 (if ever) // $fields = $instance->db->list_fields($temp); // for ($i=0; $i < count($fields); $i++) { // $fields[$i] = $temp . '.' . $fields[$i] . ' AS `' . $temp . '.' . $fields[$i] . '`'; // } // $internal_properties = implode(', ', $fields); $internal_properties = '`' . $temp . '`.*'; } if ( ! empty($internal_properties)) { $log->detail = 'INTERNAL PROPERTIES: ' . $internal_properties; stdlog($log); } return $internal_properties; } } if ( ! function_exists('response_get_limit')) { /** * [response_get_limit description] * @param string $format [description] * @return [type] [description] */ function response_get_limit($get = '', $post = '', $format = '', $default_limit = 1000) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_limit'; $log->status = 'parsing'; $log->summary = 'get action'; $instance = & get_instance(); $limit = 0; if ( ! empty($get)) { $limit = intval($get); $log->summary = 'Set limit according to GET.'; } if ( ! empty($post)) { $limit = intval($post); $log->summary = 'Set limit according to POST.'; } if ($format === 'screen' && empty($limit)) { $limit = intval($default_limit); $log->summary = 'Set limit according to SCREEN default.'; } if ($format === 'json' && empty($limit)) { $limit = intval($default_limit); $log->summary = 'Set limit according to JSON default.'; } if ( ! empty($limit)) { $log->detail = 'LIMIT: ' . $limit; stdlog($log); } return $limit; } } if ( ! function_exists('response_get_links')) { /** * Derive our links * @param string $collection [description] * @param string $id [description] * @param string $sub_resource [description] * @param string $sub_resource_id [description] * @return class Our links */ function response_get_links($collection = '', $id = '', $sub_resource = '', $sub_resource_id = '') { $instance = & get_instance(); $links = new stdClass(); $links->self = $instance->config->config['base_url'] . 'index.php/' . $collection; if ( ! is_null($id)) { $links->self .= '/' . $id; } if ($sub_resource !== '') { $links->self .= '/' . $sub_resource; } if ( ! empty($sub_resource_id)) { $links->self .= '/' . $sub_resource_id; } $links->first = null; $links->last = null; $links->next = null; $links->prev = null; return $links; } } if ( ! function_exists('response_get_offset')) { /** * Determine the requested offset * @return [type] [description] */ function response_get_offset() { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_offset'; $log->status = 'parsing'; $log->summary = 'get action'; $offset = 0; if (isset($_GET['offset'])) { $offset = intval($_GET['offset']); $log->summary = 'Set offset according to GET.'; stdlog($log); } if (isset($_POST['offset'])) { $offset = intval($_POST['offset']); $log->summary = 'Set offset according to POST.'; stdlog($log); } if ( ! empty($offset)) { $log->detail = 'OFFSET: ' . $offset; stdlog($log); } return $offset; } } if ( ! function_exists('response_get_org_list')) { /** * Return the Org IDs list for the given collection for a supplied user * @param string $collection [description] * @param [type] $user [description] * @return [type] [description] */ function response_get_org_list($collection = '', $user = null) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_org_list'; $log->status = 'parsing'; $log->summary = 'get org list'; if ($collection === '' OR $user === null) { $log->severity = 5; $log->detail = 'Either no collection or no user supplied.'; stdlog($log); return; } $instance = & get_instance(); $org_list = array(); switch ($collection) { case 'agents': case 'applications': case 'baselines': case 'baselines_policies': case 'buildings': case 'clouds': case 'clusters': case 'collectors': case 'connections': case 'credentials': case 'devices': case 'discoveries': case 'discovery_log': case 'floors': case 'integrations': case 'ldap_servers': case 'licenses': case 'locations': case 'logs': case 'networks': case 'orgs': case 'rack_devices': case 'racks': case 'rooms': case 'rows': case 'search': case 'tasks': case 'users': $log->summary = 'Set org_list according to ' . $collection . ' for DESCENDANTS.'; $org_list = array_unique(array_merge($user->orgs, $instance->m_orgs->get_user_descendants($user->id))); break; case 'configuration': case 'database': case 'errors': case 'help': case 'nmis': case 'san': case 'test': case 'util': $log->summary = 'Set org_list according to ' . $collection . ' for USER.'; $org_list = $user->orgs; break; case 'dashboards': case 'discovery_scan_options': case 'fields': case 'files': case 'groups': case 'queries': case 'reports': case 'roles': case 'rules': case 'scripts': case 'summaries': case 'widgets': $log->summary = 'Set org_list according to ' . $collection . ' for PARENTS and DESCENDANTS.'; $org_list = array_unique(array_merge($user->orgs, $instance->m_orgs->get_user_descendants($user->id))); $org_list = array_unique(array_merge($org_list, $instance->m_orgs->get_user_ascendants($user->id))); $org_list[] = 1; $org_list = array_unique($org_list); break; default: $log->summary = 'Set org_list according to ' . $collection . ' for USER DEFAULT.'; $org_list = $user->orgs; break; } $org_list = implode(',', $org_list); $log->detail = 'ORG LIST: ' . json_encode($org_list); stdlog($log); return $org_list; } } if ( ! function_exists('response_get_permission_ca')) { /** * Is the user allowed to perform $action on $collection according to their role membership * @param class $user [description] * @param string $collection [description] * @param string $action [description] * @param class $received_data [description] * @param int $id [description] * @return bool [description] */ function response_get_permission_ca($user = null, $collection = '', $action = '', $received_data = null, $id = null) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_permission_ca'; $log->status = 'parsing'; $log->summary = 'get permission for collection / action'; $instance = & get_instance(); $log->detail = 'COLLECTION: ' . @$collection . ' ACTION: ' . @$action; if (empty($instance->roles) && intval($instance->config->config['internal_version']) >= 20160904) { return true; } if (empty($user->orgs)) { $instance->session->unset_userdata('user_id'); $instance->session->set_flashdata('error', 'User has no permissions on any orgs.'); redirect('logon'); } if (empty($user) OR empty($collection) OR empty($action)) { $log->severity = 4; $log->details = 'Cannot retrieve permission, missing attribute'; stdlog($log); return false; } $permissions = response_valid_permissions($collection); if ($collection === 'users' && intval($user->id) === intval($id) && $action === 'read' ) { // Always allow a user to READ their own object return true; } if ($collection === 'help') { // Always allow a user to view help return true; } if ($collection === 'errors') { // Always allow a user to view help return true; } if ($collection === 'users' && $action === 'update' && $id === $user->id && ! empty($received_data)) { // A user is allowed to update some of their own fields $allowed_attributes = array('id', 'name', 'full_name', 'email', 'lang', 'password', 'dashboard_id'); $check_permission = false; foreach (array_keys($received_data->attributes) as $key) { if ( ! in_array($key, $allowed_attributes)) { $check_permission = true; } } if ($check_permission === false) { return true; } } // TODO - move the below into the function $perm_collection = $collection; if ($collection === 'baselines_policies') { $perm_collection = 'baselines'; } if ( ! $instance->m_users->get_user_permission($user->id, $perm_collection, $permissions[$action]) and $instance->config->config['internal_version'] >= '20160904') { log_error('ERR-0015', $collection . ':' . $permissions[$action]); $log->details = 'User not permittied to perform ' . $action . ' on ' . $collection; $log->severity = 5; stdlog($log); return false; } $log->summary = 'User permittied to perform ' . $action . ' on ' . $collection; stdlog($log); return true; } } if ( ! function_exists('response_get_permission_id')) { /** * [response_get_permission_id description] * @param [type] $user [description] * @param string $collection [description] * @param string $action [description] * @param [type] $received_data [description] * @param [type] $id [description] * @return [type] [description] */ function response_get_permission_id($user, $collection, $action, $received_data, $id) { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_permission_id'; $log->status = 'parsing'; $log->summary = 'get permission for collection / action / ID'; $log->detail = 'COLLECTION: ' . @$collection . ' ACTION: ' . @$action . ' ID: ' . @$id; $instance = & get_instance(); $collections = array('charts', 'configuration', 'database', 'errors', 'ldap_servers', 'logs', 'nmis', 'queue', 'report', 'roles'); if ( empty($id) OR intval($id) === 888888888888 OR in_array($collection, $collections)) { $log->summary = 'User permittied to access ' . $collection; stdlog($log); return true; } if ( ! $instance->m_users->get_user_collection_org_permission($collection, $id)) { log_error('ERR-0018', $collection . ':' . $action); $log->severity = 5; $log->summary = 'User not permittied to perform ' . $action . ' on ' . $collection . ' ID ' . $id; stdlog($log); return false; } // check (if we're supplying data) that the OrgID is one we are allowed to supply if ($action === 'create' OR $action === 'update' OR $action === 'import' OR $action === 'delete') { $temp = explode(',', $user->org_list); // org_id if ( ! empty($received_data->org_id)) { $allowed = false; foreach ($temp as $key => $value) { if ($received_data->org_id === $value) { $allowed = true; } } if ( ! $allowed) { log_error('ERR-0018', $collection . ':' . $action); $log->severity = 5; $log->summary = 'User not permittied to perform ' . $action . ' on ' . $collection . ' ID ' . $id; stdlog($log); return false; } } // devices_assigned_to_org if ( ! empty($received_data->devices_assigned_to_org)) { $allowed = false; foreach ($temp as $key => $value) { if ($received_data->devices_assigned_to_org === $value) { $allowed = true; } } if ( ! $allowed) { log_error('ERR-0018', $collection . ':' . $action); $log->severity = 5; $log->summary = 'User not ermittied to perform ' . $action . ' on ' . $collection . ' ID ' . $id; stdlog($log); return false; } } $log->summary = 'User permittied to perform ' . $action . ' on OrgID ' . @$received_data->org_id; } stdlog($log); return true; } } if ( ! function_exists('response_get_properties')) { /** * Determine and validate or supply default property list * @param string $collection The request collection * @param string $action The request action * @param string $sub_resource The request sub_resource (if exists) * @return string A comma separeted list of properties */ function response_get_properties($collection = '', $action = '', $sub_resource = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_properties'; $log->status = 'parsing'; $log->summary = 'get properties'; $instance = & get_instance(); $properties = ''; if ($sub_resource === 'devices') { $sub_resource = 'system'; } $table = $collection; if ($table === 'devices') { $table = 'system'; } if ( ! empty($_GET['properties'])) { $properties = $_GET['properties']; $log->summary = 'Set properties according to GET.'; // Allow for format of properties=["id", "name", "status"] if ($temp = json_decode($properties)) { $properties = implode(',', $temp); $log->summary = 'Set properties according to GET JSON.'; } } if ( ! empty($_POST['properties'])) { $properties = $_POST['properties']; $log->summary = 'Set properties according to POST.'; // Allow for format of properties=["id", "name", "status"] if ($temp = json_decode($properties)) { $properties = implode(',', $temp); $log->summary = 'Set properties according to POST JSON.'; } } if ($collection === 'devices') { if ($action === 'collection' && ($properties === 'default' OR $properties === '') && ($sub_resource === '' OR $sub_resource === 'system')) { if ($properties === 'default') { $log->summary = 'Set properties to config DEFAULT.'; $properties = $instance->config->config['devices_default_retrieve_columns']; } else { $log->summary = 'Set properties because BLANK.'; $properties = 'system.id,system.icon,system.type,system.name,system.domain,system.ip,system.identification,system.description,system.manufacturer,system.os_family,system.status'; } } else if ($action === 'collection' && $sub_resource !== '') { $log->summary = 'Set properties to ALL.'; $properties = $sub_resource . '.*'; } } if ($properties === 'all' OR $properties === '*') { $properties = $table . '.' . implode(','.$table.'.', $instance->db->list_fields($table)); $log->summary = 'Set properties to TABLE ALL.'; } if ( ! empty($properties) and $properties !== $sub_resource . '.*') { // Validate the properties are database columns $properties = explode(',', $properties); for ($i=0; $i < count($properties); $i++) { if (strpos($properties[$i], '.') !== false) { $temp = explode('.', $properties[$i]); if ( ! $instance->db->field_exists($temp[1], $temp[0])) { $log->detail = 'Invalid property supplied (' . htmlentities($properties[$i]) . '), removed.'; unset($properties[$i]); stdlog($log); } } else { if ( ! $instance->db->field_exists($properties[$i], $table)) { $log->detail = 'Invalid property supplied (' . htmlentities($properties[$i]) . '), removed.'; unset($properties[$i]); stdlog($log); } } } $properties = implode(',', $properties); } if ($properties === '' && $collection !== 'devices') { $properties = '.*'; $log->summary = 'Set properties according to NON-DEVICES DEFAULT.'; } // perform some simple data cleansing if (is_array($properties)) { $properties = implode(',', $properties); } $temp = $properties; $properties = preg_replace('/[^A-Za-z0-9\.\_\,\*]/', '', $properties); if ($temp !== $properties) { // something was filtered $log->summary = 'Set properties according to FILTERING.'; } if ( ! empty($properties)) { $log->detail = 'PROPERTIES: ' . $properties; stdlog($log); } return $properties; } } if ( ! function_exists('response_get_sort')) { /** * Determine the requested sort * @param string $collection The request collection * @return string [description] */ function response_get_sort($collection = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_sort'; $log->status = 'parsing'; $log->summary = 'get sub_resource'; $instance = & get_instance(); $sort = ''; if (isset($_GET['sort'])) { $sort = $_GET['sort']; $log->summary = 'Set sort according to GET.'; } if (isset($_POST['sort'])) { $sort = $_POST['sort']; $log->summary = 'Set sort according to POST.'; } $sort = str_replace('+', '', $sort); if ( ! empty($sort)) { $properties = explode(',', $sort); for ($i=0; $i < count($properties); $i++) { $field = $properties[$i]; if (substr($field, 0, 1) === '-') { $field = substr($field, 1); } $temp = array(); if (strpos($field, '.') !== false) { $temp = explode('.', $field); } else { $temp[0] = $collection; if ($temp[0] === 'devices') { $temp[0] = 'system'; } $temp[1] = $field; } if ( ! $instance->db->field_exists($temp[1], $temp[0])) { $log->severity = 5; $log->summary = 'Invalid sort attribute supplied (' . htmlentities($properties[$i]) . '), removed.'; unset($properties[$i]); } else { if (substr($properties[$i], 0, 1) === '-') { $properties[$i] = $temp[0] . '.' . $temp[1] . ' DESC'; } else { $properties[$i] = $temp[0] . '.' . $temp[1]; } } } $sort = implode(',', $properties); } if ( ! empty($sort)) { $log->detail = 'SORT: ' . $sort; stdlog($log); } return $sort; } } if ( ! function_exists('response_get_sub_resource')) { /** * Determine the requested included sub-collections * @param string $collection [description] * @param string $format [description] * @return string The requested includes, or all valid includes, or none */ function response_get_sub_resource($get = '', $post = '', $uri = '', $collection = '', $format = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_sub_resource'; $log->status = 'parsing'; $log->summary = 'get sub_resource'; $sub_resource = ''; if ( ! empty($get)) { $sub_resource = $get; $log->summary = 'Set sub_resource according to GET.'; } if ( ! empty($post)) { $sub_resource = $_POST['sub_resource']; $log->summary = 'Set sub_resource according to POST.'; } if ( ! empty($uri)) { $sub_resource = $uri; $log->summary = 'Set sub_resource according to URI.'; } if ( ! empty($sub_resource) && $collection === 'devices') { $valid_sub_resources = response_valid_sub_resources(); if ($format === 'screen' && (empty($sub_resource) OR $sub_resource === '*' OR $sub_resource === 'all')) { $sub_resource = implode(',', $valid_sub_resources); } else { $temp = explode(',', $sub_resource); for ($i=0; $i < count($temp); $i++) { if ( ! in_array($temp[$i], $valid_sub_resources)) { unset($temp[$i]); } } $sub_resource = implode(',', $temp); } } if ( ! empty($sub_resource)) { $log->detail = 'SUB_RESOURCE: ' . $sub_resource; stdlog($log); } return $sub_resource; } } if ( ! function_exists('response_get_sub_resource_id')) { /** * Determine the ID of the sub_resource * @param string $sub_resource From $response->meta * @return int The requested resource ID */ function response_get_sub_resource_id($sub_resource = '') { $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_sub_resource_id'; $log->status = 'parsing'; $log->summary = 'get sub_resource_id'; $instance = & get_instance(); $sub_resource_id = ''; if ( ! empty($sub_resource)) { $sub_resource_id = intval((string)urldecode($instance->uri->segment(4, ''))); $log->summary = 'Set sub_resource_id according to URI.'; } if (isset($_GET['sub_resource_id'])) { $sub_resource_id = intval($_GET['sub_resource_id']); $log->summary = 'Set sub_resource_id according to GET.'; } if (isset($_POST['sub_resource_id'])) { $sub_resource_id = intval($_POST['sub_resource_id']); $log->summary = 'Set sub_resource_id according to POST.'; } if ( ! empty($sub_resource_id)) { $log->detail = 'SUB_RESOURCE_ID: ' . $sub_resource_id; stdlog($log); } return $sub_resource_id; } } if ( ! function_exists('response_get_version')) { /** * Determine if the user specifically requested a version. If so, adjust the URI. * @return int The version number, defaults to 1 */ function response_get_version($uri_segments = null, $accept_header = '') { return 1; $log = new stdClass(); $log->severity = 7; $log->type = 'system'; $log->object = 'response_helper'; $log->function = 'response_helper::response_get_version'; $log->status = 'parsing'; $log->summary = 'Set version per default.'; if (empty($uri_segments) or ! is_array($uri_segments)) { $log->summary = 'Bad segments array passed to function'; stdlog($log); return 1; } $instance = & get_instance(); $version = 1; if ( ! empty($uri_segments[1]) && ($uri_segments[1] === 'api' OR $uri_segments[1] === 'v1' OR $uri_segments[1] === 'v2')) { if ($uri_segments[1] === 'api') { $version = intval($instance->uri->segment(2)); $log->summary = 'Set version according to URI api segment.'; } else if ($uri_segments[1] === 'v1') { $version = 1; $log->summary = 'Set version according to URI v1 segment.'; } else if ($uri_segments[1] === 'v2') { $version = 2; $log->summary = 'Set version according to URI v2 segment.'; } } else if (strpos($accept_header, 'application/json;version=') !== false) { $version = intval(str_replace('application/json;version=', '', $accept_header)); $log->summary = 'Set version according to headers.'; } if ($version !== 1 && $version !== 2) { $version = 1; } $log->detail = 'VERSION: ' . $version; stdlog($log); return $version; } } if ( ! function_exists('response_set_uri')) { /** * Determine if the user specifically requested a version. If so, adjust the URI. * @return array The URI after removing any API version items */ function response_set_uri($uri_segments = null) { if ( ! empty($uri_segments[1]) && is_array($uri_segments) && ($uri_segments[1] === 'api' OR $uri_segments[1] === 'v1' OR $uri_segments[1] === 'v2')) { if ($uri_segments[1] === 'api') { unset($uri_segments[1]); unset($uri_segments[2]); } else if ($uri_segments[1] === 'v1') { unset($uri_segments[1]); } else if ($uri_segments[1] === 'v2') { unset($uri_segments[1]); } } array_unshift($uri_segments, ''); $filtered_segments = array_values($uri_segments); return $filtered_segments; } } if ( ! function_exists('response_valid_actions')) { /** * An array of valid actions * @return array */ function response_valid_actions() { return array('bulk_update_form', 'collection', 'create', 'create_form', 'debug', 'delete', 'download', 'execute', 'export', 'export_form', 'import', 'import_form', 'read', 'reset', 'sub_resource_create', 'sub_resource_read', 'sub_resource_create_form', 'sub_resource_delete', 'sub_resource_download', 'test', 'update'); } } if ( ! function_exists('response_valid_collections')) { /** * An array of valid collections * @return array */ function response_valid_collections() { return array('agents','applications','attributes','baselines','baselines_policies','buildings','chart','clouds','clusters','collectors','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_log','discovery_scan_options','errors','fields','files','floors','groups','help','integrations','ldap_servers','licenses','locations','logs','networks','nmis','orgs','queries','queue','racks','rack_devices','reports','roles','rooms','rows','rules','scripts','search','sessions','summaries','tasks','users','widgets'); } } if ( ! function_exists('response_valid_current')) { /** * An array of valid current * @return array */ function response_valid_current() { return array('y','n','all','delta','full'); } } if ( ! function_exists('response_valid_formats')) { /** * An array of valid response formats * @return array */ function response_valid_formats() { $valid_formats = array('json','json_data','highcharts','html','screen','xml','csv','sql','table'); return $valid_formats; } } if ( ! function_exists('response_valid_includes')) { /** * An array of valid includes * @return array */ function response_valid_includes() { return array('application', 'attachment', 'audit_log', 'bios', 'change_log', 'cluster', 'credential', 'discovery_log', 'disk', 'dns', 'edit_log', 'fields', 'file', 'image', 'ip', 'location', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'purchase', 'rack_devices', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); } } if ( ! function_exists('response_valid_permissions')) { /** * Set permissions array. Execute depends on $collection * @param string $collection Execute depends on $collection * @return array The array. */ function response_valid_permissions($collection) { $permission = array(); $permission['bulk_update_form'] = 'c'; $permission['collection'] = 'r'; $permission['create'] = 'c'; $permission['create_form'] = 'c'; $permission['delete'] = 'd'; $permission['download'] = 'r'; if ($collection === 'database' OR $collection === 'discoveries') { $permission['execute'] = 'u'; } else { $permission['execute'] = 'r'; } $permission['import'] = 'c'; $permission['import_form'] = 'c'; $permission['read'] = 'r'; $permission['export'] = 'r'; $permission['reset'] = 'd'; $permission['sub_resource_create'] = 'c'; $permission['sub_resource_create_form'] = 'c'; $permission['sub_resource_delete'] = 'd'; $permission['sub_resource_download'] = 'r'; $permission['sub_resource_read'] = 'r'; $permission['test'] = 'u'; $permission['update'] = 'u'; $permission['update_form'] = 'u'; $permission['unknown'] = 'unknown action'; return $permission; } } if ( ! function_exists('response_valid_sub_resources')) { /** * An array of valid sub_resources (for devices) * @return array */ function response_valid_sub_resources() { return array('application', 'attachment', 'audit_log', 'bios', 'change_log', 'cluster', 'credential', 'discovery', 'discovery_log', 'disk', 'dns', 'edit_log', 'image', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'partition_graph', 'policy', 'print_queue', 'processor', 'route', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'user', 'user_group', 'variable', 'video', 'vm', 'windows', 'report', 'query', 'group'); } } if ( ! function_exists('valid_reserved_words')) { /** * An array of valid URL reserved words * @return array */ function response_valid_reserved_words() { return array('action', 'as_at', 'current', 'debug', 'format', 'graph', 'groupby', 'ids', 'include', 'limit', 'offset', 'properties', 'query', 'report_name', 'search', 'sort', 'sub_resource', 'sub_resource_id'); } } // End of file response_helper.php // Location: ./helpers/response_helper.php