0) && (!is_numericint($pconfig['ntporphan']) || ($pconfig['ntporphan'] < 1) || ($pconfig['ntporphan'] > 15))) { $input_errors[] = gettext("The supplied value for NTP Orphan Mode is invalid."); } if (!$input_errors) { if (is_array($_POST['interface'])) { $config['ntpd']['interface'] = implode(",", $_POST['interface']); } elseif (isset($config['ntpd']['interface'])) { unset($config['ntpd']['interface']); } if (!empty($_POST['gpsport']) && file_exists('/dev/'.$_POST['gpsport'])) { $config['ntpd']['gpsport'] = $_POST['gpsport']; } elseif (isset($config['ntpd']['gpsport'])) { unset($config['ntpd']['gpsport']); } unset($config['ntpd']['prefer']); unset($config['ntpd']['noselect']); unset($config['ntpd']['ispool']); $timeservers = ''; for ($i = 0; $i < NUMTIMESERVERS; $i++) { $tserver = trim($_POST["server{$i}"]); if (!empty($tserver)) { $timeservers .= "{$tserver} "; if (!empty($_POST["servprefer{$i}"])) { $config['ntpd']['prefer'] .= "{$tserver} "; } if (!empty($_POST["servselect{$i}"])) { $config['ntpd']['noselect'] .= "{$tserver} "; } if (!empty($_POST["servispool{$i}"])) { $config['ntpd']['ispool'] .= "{$tserver} "; } } } if (trim($timeservers) == "") { $timeservers = "pool.ntp.org"; } $config['system']['timeservers'] = trim($timeservers); $config['ntpd']['orphan'] = trim($pconfig['ntporphan']); if (!empty($_POST['logpeer'])) { $config['ntpd']['logpeer'] = $_POST['logpeer']; } elseif (isset($config['ntpd']['logpeer'])) { unset($config['ntpd']['logpeer']); } if (!empty($_POST['logsys'])) { $config['ntpd']['logsys'] = $_POST['logsys']; } elseif (isset($config['ntpd']['logsys'])) { unset($config['ntpd']['logsys']); } if (!empty($_POST['clockstats'])) { $config['ntpd']['clockstats'] = $_POST['clockstats']; } elseif (isset($config['ntpd']['clockstats'])) { unset($config['ntpd']['clockstats']); } if (!empty($_POST['loopstats'])) { $config['ntpd']['loopstats'] = $_POST['loopstats']; } elseif (isset($config['ntpd']['loopstats'])) { unset($config['ntpd']['loopstats']); } if (!empty($_POST['peerstats'])) { $config['ntpd']['peerstats'] = $_POST['peerstats']; } elseif (isset($config['ntpd']['peerstats'])) { unset($config['ntpd']['peerstats']); } if ((empty($_POST['statsgraph'])) == (isset($config['ntpd']['statsgraph']))) { $enable_rrd_graphing = true; } if (!empty($_POST['statsgraph'])) { $config['ntpd']['statsgraph'] = $_POST['statsgraph']; } elseif (isset($config['ntpd']['statsgraph'])) { unset($config['ntpd']['statsgraph']); } if (isset($enable_rrd_graphing)) { enable_rrd_graphing(); } if (!empty($_POST['leaptext'])) { $config['ntpd']['leapsec'] = base64_encode($_POST['leaptext']); } elseif (isset($config['ntpd']['leapsec'])) { unset($config['ntpd']['leapsec']); } if (is_uploaded_file($_FILES['leapfile']['tmp_name'])) { $config['ntpd']['leapsec'] = base64_encode(file_get_contents($_FILES['leapfile']['tmp_name'])); } write_config("Updated NTP Server Settings"); $changes_applied = true; $retval = 0; $retval |= system_ntp_configure(); } } function build_interface_list() { global $pconfig; $iflist = array('options' => array(), 'selected' => array()); $interfaces = get_configured_interface_with_descr(); foreach ($interfaces as $iface => $ifacename) { if (!is_ipaddr(get_interface_ip($iface)) && !is_ipaddrv6(get_interface_ipv6($iface))) { continue; } $iflist['options'][$iface] = $ifacename; if (in_array($iface, $pconfig['interface'])) { array_push($iflist['selected'], $iface); } } return($iflist); } $pconfig = &$config['ntpd']; if (empty($pconfig['interface'])) { $pconfig['interface'] = array(); } else { $pconfig['interface'] = explode(",", $pconfig['interface']); } $pgtitle = array(gettext("Services"), gettext("NTP"), gettext("Settings")); $pglinks = array("", "@self", "@self"); $shortcut_section = "ntp"; include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } if ($changes_applied) { print_apply_result_box($retval); } $tab_array = array(); $tab_array[] = array(gettext("Settings"), true, "services_ntpd.php"); $tab_array[] = array(gettext("ACLs"), false, "services_ntpd_acls.php"); $tab_array[] = array(gettext("Serial GPS"), false, "services_ntpd_gps.php"); $tab_array[] = array(gettext("PPS"), false, "services_ntpd_pps.php"); display_top_tabs($tab_array); $form = new Form; $form->setMultipartEncoding(); // Allow file uploads $section = new Form_Section('NTP Server Configuration'); $iflist = build_interface_list(); $section->addInput(new Form_Select( 'interface', 'Interface', $iflist['selected'], $iflist['options'], true ))->setHelp('Interfaces without an IP address will not be shown.%1$s' . 'Selecting no interfaces will listen on all interfaces with a wildcard.%1$s' . 'Selecting all interfaces will explicitly listen on only the interfaces/IPs specified.', '
'); $timeservers = explode(' ', $config['system']['timeservers']); $maxrows = max(count($timeservers), 1); $auto_pool_suffix = "pool.ntp.org"; for ($counter=0; $counter < $maxrows; $counter++) { $group = new Form_Group($counter == 0 ? 'Time Servers':''); $group->addClass('repeatable'); $group->setAttribute('max_repeats', NUMTIMESERVERS); $group->setAttribute('max_repeats_alert', sprintf(gettext('%d is the maximum number of configured servers.'), NUMTIMESERVERS)); $group->add(new Form_Input( 'server' . $counter, null, 'text', $timeservers[$counter], ['placeholder' => 'Hostname'] ))->setWidth(3); $group->add(new Form_Checkbox( 'servprefer' . $counter, null, null, isset($config['ntpd']['prefer']) && isset($timeservers[$counter]) && substr_count($config['ntpd']['prefer'], $timeservers[$counter]) ))->sethelp('Prefer'); $group->add(new Form_Checkbox( 'servselect' . $counter, null, null, isset($config['ntpd']['noselect']) && isset($timeservers[$counter]) && substr_count($config['ntpd']['noselect'], $timeservers[$counter]) ))->sethelp('No Select'); $group->add(new Form_Checkbox( 'servispool' . $counter, null, null, (substr_compare($timeservers[$counter], $auto_pool_suffix, strlen($timeservers[$counter]) - strlen($auto_pool_suffix), strlen($auto_pool_suffix)) === 0) || (isset($config['ntpd']['ispool']) && isset($timeservers[$counter]) && substr_count($config['ntpd']['ispool'], $timeservers[$counter])) ))->sethelp('Is a Pool'); $group->add(new Form_Button( 'deleterow' . $counter, 'Delete', null, 'fa-trash' ))->addClass('btn-warning'); $section->add($group); } $section->addInput(new Form_Button( 'addrow', 'Add', null, 'fa-plus' ))->addClass('btn-success'); $section->addInput(new Form_StaticText( null, $btnaddrow ))->setHelp( 'NTP will only sync if a majority of the servers agree on the time. For best results you should configure between 3 and 5 servers ' . '(%4$sNTP support pages recommend at least 4 or 5%5$s), or a pool. If only one server is configured, it %2$swill%3$s be believed, and if 2 servers ' . 'are configured and they disagree, %2$sneither%3$s will be believed. Options:%1$s' . '%2$sPrefer%3$s - NTP should favor the use of this server more than all others.%1$s' . '%2$sNo Select%3$s - NTP should not use this server for time, but stats for this server will be collected and displayed.%1$s' . '%2$sIs a Pool%3$s - this entry is a pool of NTP servers and not a single address. This is assumed for *.pool.ntp.org.', '
', '', '', '', '' ); $section->addInput(new Form_Input( 'ntporphan', 'Orphan Mode', 'text', $pconfig['orphan'], ['placeholder' => "12"] ))->setHelp('Orphan mode allows the system clock to be used when no other clocks are available. ' . 'The number here specifies the stratum reported during orphan mode and should normally be set to a number high enough ' . 'to insure that any other servers available to clients are preferred over this server (default: 12).'); $section->addInput(new Form_Checkbox( 'statsgraph', 'NTP Graphs', 'Enable RRD graphs of NTP statistics (default: disabled).', $pconfig['statsgraph'] )); $section->addInput(new Form_Checkbox( 'logpeer', 'Logging', 'Log peer messages (default: disabled).', $pconfig['logpeer'] )); $section->addInput(new Form_Checkbox( 'logsys', null, 'Log system messages (default: disabled).', $pconfig['logsys'] ))->setHelp('These options enable additional messages from NTP to be written to the System Log %1$sStatus > System Logs > NTP%2$s', '', '.'); // Statistics logging section $btnadv = new Form_Button( 'btnadvstats', 'Display Advanced', null, 'fa-cog' ); $btnadv->setAttribute('type','button')->addClass('btn-info btn-sm'); $section->addInput(new Form_StaticText( 'Statistics Logging', $btnadv ))->setHelp('Warning: These options will create persistent daily log files in /var/log/ntp.'); $section->addInput(new Form_Checkbox( 'clockstats', null, 'Log reference clock statistics (default: disabled).', $pconfig['clockstats'] )); $section->addInput(new Form_Checkbox( 'loopstats', null, 'Log clock discipline statistics (default: disabled).', $pconfig['loopstats'] )); $section->addInput(new Form_Checkbox( 'peerstats', null, 'Log NTP peer statistics (default: disabled).', $pconfig['peerstats'] )); // Leap seconds section $btnadv = new Form_Button( 'btnadvleap', 'Display Advanced', null, 'fa-cog' ); $btnadv->setAttribute('type','button')->addClass('btn-info btn-sm'); $section->addInput(new Form_StaticText( 'Leap seconds', $btnadv ))->setHelp( 'Leap seconds may be added or subtracted at the end of June or December. Leap seconds are administered by the ' . '%1$sIERS%2$s, who publish them in their Bulletin C approximately 6 - 12 months in advance. Normally this correction ' . 'should only be needed if the server is a stratum 1 NTP server, but many NTP servers do not advertise an upcoming leap ' . 'second when other NTP servers synchronise to them.%3$s%4$sIf the leap second is important to your network services, ' . 'it is %6$sgood practice%2$s to download and add the leap second file at least a day in advance of any time correction%5$s.%3$s ' . 'More information and files for downloading can be found on their %1$swebsite%2$s, and also on the %7$NIST%2$s and %8$sNTP%2$s websites.', '', '', '
', '', '', '', '', '' ); $section->addInput(new Form_Textarea( 'leaptext', null, base64_decode(chunk_split($pconfig['leapsec'])) ))->setHelp('Enter Leap second configuration as text OR select a file to upload.'); $section->addInput(new Form_Input( 'leapfile', null, 'file' ))->addClass('btn-default'); $form->add($section); print($form); ?>