Some grep implementations detect binary data and return success without matching whole line. This might be an issue for the DHCPv6 NTP FQDN check. The GNU grep in the C locale seems to check only for the NUL character, which cannot be passed in an environment variable, but other implementations might behave differently and there doesn't seem to be a portable way to force matching the whole line. Instead of the grep command, check for invalid characters by comparing the length of the input passed through "tr -d -c".
49 lines
1.3 KiB
Bash
49 lines
1.3 KiB
Bash
#!/bin/sh
|
|
# This is a NetworkManager dispatcher script for chronyd to update
|
|
# its NTP sources with servers from DHCP options passed by NetworkManager
|
|
# in the DHCP4_NTP_SERVERS and DHCP6_DHCP6_NTP_SERVERS environment variables.
|
|
|
|
export LC_ALL=C
|
|
|
|
interface=$1
|
|
action=$2
|
|
|
|
chronyc=/usr/bin/chronyc
|
|
server_options=iburst
|
|
server_dir=/var/run/chrony-dhcp
|
|
|
|
dhcp_server_file=$server_dir/$interface.sources
|
|
dhcp_ntp_servers="$DHCP4_NTP_SERVERS $DHCP6_DHCP6_NTP_SERVERS"
|
|
|
|
add_servers_from_dhcp() {
|
|
rm -f "$dhcp_server_file"
|
|
for server in $dhcp_ntp_servers; do
|
|
# Check for invalid characters (from the DHCPv6 NTP FQDN suboption)
|
|
len1=$(printf '%s' "$server" | wc -c)
|
|
len2=$(printf '%s' "$server" | tr -d -c 'A-Za-z0-9:.-' | wc -c)
|
|
if [ "$len1" -ne "$len2" ] || [ "$len2" -lt 1 ] || [ "$len2" -gt 255 ]; then
|
|
continue
|
|
fi
|
|
|
|
printf 'server %s %s\n' "$server" "$server_options" >> "$dhcp_server_file"
|
|
done
|
|
$chronyc reload sources > /dev/null 2>&1 || :
|
|
}
|
|
|
|
clear_servers_from_dhcp() {
|
|
if [ -f "$dhcp_server_file" ]; then
|
|
rm -f "$dhcp_server_file"
|
|
$chronyc reload sources > /dev/null 2>&1 || :
|
|
fi
|
|
}
|
|
|
|
mkdir -p $server_dir
|
|
|
|
case "$action" in
|
|
up|dhcp4-change|dhcp6-change)
|
|
add_servers_from_dhcp;;
|
|
down)
|
|
clear_servers_from_dhcp;;
|
|
esac
|
|
|
|
exit 0
|