hasGlobalAdmin()) { $force_save = isset($_POST['force_save']) && $_POST['force_save'] == 'on'; $device->poller_group = $_POST['poller_group'] ?? 0; $snmp_enabled = ($_POST['snmp'] == 'on'); if ($snmp_enabled) { $device->snmp_disable = 0; $device->snmpver = $_POST['snmpver']; $device->port = $_POST['port'] ?: Config::get('snmp.port'); $device->transport = $_POST['transport'] ?: $transport = 'udp'; $device->port_association_mode = $_POST['port_assoc_mode']; $max_repeaters = $_POST['max_repeaters'] ?? ''; $max_oid = $_POST['max_oid']; $device->retries = $_POST['retries'] ?: null; $device->timeout = $_POST['timeout'] ?: null; if ($device->snmpver == 'v3') { $device->community = ''; // if v3 works, we don't need a community $device->authalgo = $_POST['authalgo']; $device->authlevel = $_POST['authlevel']; $device->authname = $_POST['authname']; $device->authpass = $_POST['authpass']; $device->cryptoalgo = $_POST['cryptoalgo']; $device->cryptopass = $_POST['cryptopass']; } elseif ($_POST['community'] != '********') { $device->community = $_POST['community']; } } else { // snmp is disabled $device->features = null; $device->hardware = $_POST['hardware']; $device->icon = null; $device->os = $_POST['os'] ? $_POST['os_id'] : 'ping'; $device->snmp_disable = 1; $device->sysName = $_POST['sysName'] ?: null; $device->version = null; } $device_is_snmpable = false; $device_updated = false; if ($force_save !== true && $snmp_enabled) { $helper = new \LibreNMS\Polling\ConnectivityHelper($device); $device_is_snmpable = $helper->isSNMPable(); } if ($force_save === true || ! $snmp_enabled || $device_is_snmpable) { // update devices table $device_updated = $device->save(); } else { $device->refresh(); // forget all pending changes } if ($snmp_enabled && ($force_save === true || $device_is_snmpable)) { // update devices_attribs table // note: // set_dev_attrib and del_dev_attrib *only* return (bool) // setAttrib() returns true if it was set and false if it was not (e.g. it didn't change) // forgetAttrib() returns true if it was deleted and false if it was not (e.g. it didn't exist) // Symfony throws FatalThrowableError on error $devices_attribs = ['snmp_max_repeaters', 'snmp_max_oid']; foreach ($devices_attribs as $devices_attrib) { // defaults $feedback_prefix = $devices_attrib; $form_value = null; $form_value_is_numeric = false; // does not need to be a number greater than zero if ($devices_attrib == 'snmp_max_repeaters') { $feedback_prefix = 'SNMP Max Repeaters'; $form_value = $max_repeaters; $form_value_is_numeric = true; } if ($devices_attrib == 'snmp_max_oid') { $feedback_prefix = 'SNMP Max OID'; $form_value = $max_oid; $form_value_is_numeric = true; } $get_devices_attrib = get_dev_attrib($device, $devices_attrib); $set_devices_attrib = false; // testing $set_devices_attrib === false is not a true indicator of a failure if ($form_value != $get_devices_attrib && $form_value_is_numeric && is_numeric($form_value) && $form_value != 0) { $device->setAttrib($devices_attrib, $form_value); } if ($form_value != $get_devices_attrib && ! $form_value_is_numeric) { $device->setAttrib($devices_attrib, $form_value); } if ($form_value != $get_devices_attrib && $form_value_is_numeric && ! is_numeric($form_value)) { $device->forgetAttrib($devices_attrib); } if ($form_value != $get_devices_attrib && ! $form_value_is_numeric && $form_value == '') { $device->forgetAttrib($devices_attrib); } if ($form_value != $get_devices_attrib && $set_devices_attrib) { unset($device->attribs); // unload relation $set_devices_attrib = $device->getAttrib($devices_attrib); // re-check the db value } if ($form_value != $get_devices_attrib && $form_value == $set_devices_attrib && (is_null($set_devices_attrib) || $set_devices_attrib == '')) { $update_message[] = "$feedback_prefix deleted"; } if ($form_value != $get_devices_attrib && $form_value == $set_devices_attrib && (! is_null($set_devices_attrib) && $set_devices_attrib != '')) { $update_message[] = "$feedback_prefix updated to $set_devices_attrib"; } if ($form_value != $get_devices_attrib && $form_value != $set_devices_attrib) { $update_failed_message[] = "$feedback_prefix update failed."; } unset($get_devices_attrib, $set_devices_attrib); } unset($devices_attrib); } if ($device_updated) { $update_message[] = 'Device record updated'; } if ($snmp_enabled && ($force_save !== true && ! $device_is_snmpable)) { $update_failed_message[] = 'Could not connect to ' . htmlspecialchars($device->hostname) . ' with those SNMP settings. To save anyway, turn on Force Save.'; $update_message[] = 'SNMP settings reverted'; } if (! $device_updated && ! isset($update_message) && ! isset($update_failed_message)) { $update_message[] = 'SNMP settings did not change'; } }//end if (Auth::user()->hasGlobalAdmin()) }//end if ($_POST['editing']) // the following unsets are for security; the database is authoritative // i.e. prevent unintentional artifacts from being saved or used (again), posting around the form, etc. unset($_POST); // these are only used for editing and should not be used as-is unset($force_save, $poller_group, $snmp_enabled); unset($community, $max_repeaters, $max_oid, $port, $port_assoc_mode, $retries, $snmpver, $transport, $timeout); // get up-to-date database values for use on the form $max_oid = $device->getAttrib('snmp_max_oid'); $max_repeaters = $device->getAttrib('snmp_max_repeaters'); // use PHP Flasher to print normal (success) messages, similar to Device Settings if (isset($update_message)) { if (is_array($update_message)) { foreach ($update_message as $message) { flash()->addSuccess($message); } } if (is_string($update_message)) { flash()->addSuccess($update_message); } unset($message, $update_message); } // use flash()->addError to call attention to the problem; don't let it time out if (isset($update_failed_message)) { if (is_array($update_failed_message)) { foreach ($update_failed_message as $error) { flash() ->option('timeout', 30000) ->addError($error); } } if (is_string($update_failed_message)) { flash() ->option('timeout', 30000) ->addError($update_failed_message); } unset($error, $update_failed_message); } echo "