db = db_connect(); $this->builder = $this->db->table('agents'); # Use the below to execute BaseModel::__construct # parent::__construct(); } /** * Read the collection from the database * * @param $resp object An object containing the properties, filter, sort and limit as passed by the user * * @return array An array of formatted entries */ public function collection(object $resp): array { $properties = $resp->meta->properties; $properties[] = "orgs.name as `orgs.name`"; $properties[] = "orgs.id as `orgs.id`"; $this->builder->select($properties, false); $this->builder->join('orgs', $resp->meta->collection . '.org_id = orgs.id', 'left'); foreach ($resp->meta->filter as $filter) { if (in_array($filter->operator, ['!=', '>=', '<=', '=', '>', '<', 'like', 'not like'])) { $this->builder->{$filter->function}($filter->name . ' ' . $filter->operator, $filter->value); } else { $this->builder->{$filter->function}($filter->name, $filter->value); } } $this->builder->orderBy($resp->meta->sort); $this->builder->limit($resp->meta->limit, $resp->meta->offset); $query = $this->builder->get(); if ($this->sqlError($this->db->error())) { return array(); } return format_data($query->getResult(), $resp->meta->collection); } /** * Create an individual item in the database * * @param object $data The data attributes * * @return int|false The Integer ID of the newly created item, or false */ public function create($data = null): ?int { if (empty($data)) { return null; } $data = $this->createFieldData('agents', $data); if (empty($data)) { return null; } $this->builder->insert($data); if ($error = $this->sqlError($this->db->error())) { \Config\Services::session()->setFlashdata('error', json_encode($error)); return null; } return (intval($this->db->insertID())); } /** * Delete an individual item from the database, by ID * * @param int $id The ID of the requested item * * @return bool true || false depending on success */ public function delete($id = null, bool $purge = false): bool { $this->builder->delete(['id' => intval($id)]); if ($this->sqlError($this->db->error())) { return false; } if ($this->db->affectedRows() !== 1) { return false; } return true; } public function download(int $id = 0, string $os = ''): ?string { $instance = & get_instance(); // $result = $this->read($id); // $data = $result[0]->attributes; // if (empty($id)) { // log_message('error', 'No script returned when ScriptsModel::download called with ID ' . $id); // return null; // } $filename = ROOTPATH . 'other/agent_windows.ps1'; if (!file_exists($filename)) { log_message('error', "Script does not exist on filesystem for $filename."); return null; } $file = file_get_contents($filename); // Force all line endings to be Unix style // Windows audit scripts with Unix line endings work // Unix audit scripts with Windows line endings do not work (bash for one, chokes) $file = str_replace("\r\n", "\n", $file); $file = str_replace("\r", "\n", $file); // Set our URL $file = str_replace('$url = ""', '$url = "' . base_url() . '"', $file); return $file; } /** * [execute description] * @param [type] $parameters MUST contain either a device ID or a device object, SHOULD contain an action, default is to update, SHOULD contain a discovery ID for logging * @return [type] [description] */ public function execute() { log_message('debug', 'AgentsExecute called.'); return; } /** * Return an array containing arrays of related items to be stored in resp->included * * @param int $id The ID of the requested item * @return array An array of anything needed for screen output */ public function includedRead(int $id = 0): array { $included = array(); $locationsModel = new \App\Models\LocationsModel(); $included['locations'] = $locationsModel->listUser(); return $included; } /** * Return an array containing arrays of related items to be stored in resp->included * * @param int $id The ID of the requested item * @return array An array of anything needed for screen output */ public function includedCreateForm(int $id = 0): array { $instance = & get_instance(); $locationsModel = new \App\Models\LocationsModel(); $include = array(); $include['locations'] = $locationsModel->listUser(); return $include; } /** * Read the entire collection from the database that the user is allowed to read * * @return array An array of formatted entries */ public function listUser($where = array(), $orgs = array()): array { if (empty($orgs)) { $instance = & get_instance(); $orgs = array_unique(array_merge($instance->user->orgs, $instance->orgsModel->getUserDescendants($instance->user->orgs, $instance->orgs))); $orgs = array_unique(array_merge($orgs, $instance->orgsModel->getUserAscendants($instance->user->orgs, $instance->orgs))); $orgs[] = 1; $orgs = array_unique($orgs); } $properties = array(); $properties[] = 'agents.*'; $properties[] = 'orgs.name as `orgs.name`'; $this->builder->select($properties, false); $this->builder->join('orgs', 'agents.org_id = orgs.id', 'left'); $this->builder->whereIn('orgs.id', $orgs); $this->builder->where($where); $query = $this->builder->get(); if ($this->sqlError($this->db->error())) { return array(); } return format_data($query->getResult(), 'agents'); } /** * Read the entire collection from the database * * @return array An array of all entries */ public function listAll(): array { $this->builder->orderBy('weight'); $query = $this->builder->get(); if ($this->sqlError($this->db->error())) { return array(); } return $query->getResult(); } /** * Read an individual item from the database, by ID * * @param int $id The ID of the requested item * * @return array The array containing the requested item */ public function read(int $id = 0): array { $query = $this->builder->getWhere(['id' => intval($id)]); if ($this->sqlError($this->db->error())) { return array(); } return format_data($query->getResult(), 'agents'); } /** * Reset a table * * @return bool Did it work or not? */ public function reset(string $table = ''): bool { if ($this->tableReset('agents')) { return true; } return false; } /** * Update an individual item in the database * * @param object $data The data attributes * * @return bool true || false depending on success */ public function update($id = null, $data = null): bool { $data = $this->updateFieldData('agents', $data); $this->builder->where('id', intval($id)); $this->builder->update($data); if ($this->sqlError($this->db->error())) { return false; } return true; } /** * The dictionary item * * @return object The stdClass object containing the dictionary */ public function dictionary(): object { $instance = & get_instance(); $collection = 'agents'; $dictionary = new stdClass(); $dictionary->table = $collection; $dictionary->columns = new stdClass(); $dictionary->attributes = new stdClass(); $dictionary->attributes->collection = array('id', 'name', 'description'); $dictionary->attributes->create = array('name','org_id'); # We MUST have each of these present and assigned a value $dictionary->attributes->fields = $this->db->getFieldNames($collection); # All field names for this table $dictionary->attributes->fieldsMeta = $this->db->getFieldData($collection); # The meta data about all fields - name, type, max_length, primary_key, nullable, default $dictionary->attributes->update = $this->updateFields($collection); # We MAY update any of these listed fields $dictionary->sentence = 'Think if this, then that for devices with an Agent installed.'; $dictionary->about = '

Agents let you audit PCs without a discovery. Install the agent and it will check-in with the server each day and audit itself. It does not matter if your computers are firewalled, audit data will still appear in Open-AudIT.

When testing if an agent should perform actions, all three tests must pass (if the test is set). Then the actions are taken.

'; $dictionary->notes = ''; $dictionary->link = $instance->dictionary->link; $dictionary->product = 'enterprise'; $dictionary->columns->id = $instance->dictionary->id; $dictionary->columns->name = $instance->dictionary->name; $dictionary->columns->org_id = $instance->dictionary->org_id; $dictionary->columns->description = $instance->dictionary->description; $dictionary->columns->weight = 'A lower number means it will be applied before other rules.'; $dictionary->columns->test_minutes = 'If this many or more minutes have passed since the device contacted the server, perform the actions.'; $dictionary->columns->test_subnet = 'If an agent reports its primary IP is in this subnet, perform the actions.'; $dictionary->columns->test_os = 'If the agent OS family (case insensitive) contains this string, perform the actions.'; #'A JSON object containing an array of attributes to match.'; $dictionary->columns->tests = 'Unused.'; $dictionary->columns->action_download = 'A URL to a file to download.'; $dictionary->columns->action_command = 'A command to run. When the agent is Windows based, this command is run from within the powershell agent.'; $dictionary->columns->action_audit = 'Should we run an audit and submit it (y/n).'; $dictionary->columns->action_uninstall = 'Should we uninstall the agent (y/n).'; $dictionary->columns->action_devices_assigned_to_location = 'Any discovered devices will be assigned to this Location when they run their audit script (if set). Links to locations.id.'; $dictionary->columns->action_devices_assigned_to_org = 'Any devices will be assigned to this Org when they run their audit script (if set). Links to orgs.id.'; #'A JSON object containing an array of attributes to change if the match occurs.'; $dictionary->columns->actions = 'Unused.'; $dictionary->columns->edited_by = $instance->dictionary->edited_by; $dictionary->columns->edited_date = $instance->dictionary->edited_date; return $dictionary; } }