xref: /freebsd/libexec/rc/rc.d/ntpd (revision f99f0ee14e3af81c23150a6a340259ca8a33d01a)
10696600cSBjoern A. Zeeb#!/bin/sh
20696600cSBjoern A. Zeeb#
30696600cSBjoern A. Zeeb#
40696600cSBjoern A. Zeeb
50696600cSBjoern A. Zeeb# PROVIDE: ntpd
60696600cSBjoern A. Zeeb# REQUIRE: DAEMON ntpdate FILESYSTEMS devfs
70696600cSBjoern A. Zeeb# BEFORE:  LOGIN
81442fed7SJohn Baldwin# KEYWORD: nojail resume shutdown
90696600cSBjoern A. Zeeb
100696600cSBjoern A. Zeeb. /etc/rc.subr
110696600cSBjoern A. Zeeb
120696600cSBjoern A. Zeebname="ntpd"
130696600cSBjoern A. Zeebdesc="Network Time Protocol daemon"
140696600cSBjoern A. Zeebrcvar="ntpd_enable"
150696600cSBjoern A. Zeebcommand="/usr/sbin/${name}"
161442fed7SJohn Baldwinextra_commands="fetch needfetch resume"
170696600cSBjoern A. Zeebfetch_cmd="ntpd_fetch_leapfile"
180696600cSBjoern A. Zeebneedfetch_cmd="ntpd_needfetch_leapfile"
191442fed7SJohn Baldwinresume_cmd="ntpd_resume"
200696600cSBjoern A. Zeebstart_precmd="ntpd_precmd"
210696600cSBjoern A. Zeeb
220696600cSBjoern A. Zeeb_ntp_tmp_leapfile="/var/run/ntpd.leap-seconds.list"
230696600cSBjoern A. Zeeb_ntp_default_dir="/var/db/ntp"
240696600cSBjoern A. Zeeb_ntp_default_driftfile="${_ntp_default_dir}/ntpd.drift"
250696600cSBjoern A. Zeeb_ntp_old_driftfile="/var/db/ntpd.drift"
260696600cSBjoern A. Zeeb
270696600cSBjoern A. Zeebpidfile="${_ntp_default_dir}/${name}.pid"
280696600cSBjoern A. Zeeb
290696600cSBjoern A. Zeebload_rc_config $name
300696600cSBjoern A. Zeeb
31*f99f0ee1SAlexander Leidinger# doesn't make sense to run in a svcj: nojail keyword
32*f99f0ee1SAlexander Leidingerntpd_svcj="NO"
33*f99f0ee1SAlexander Leidinger
34735c001bSIan Leporeleapfile_is_disabled() {
35735c001bSIan Lepore	# Return true (0) if automatic leapfile handling is disabled.
36735c001bSIan Lepore	case "$ntp_db_leapfile" in
37735c001bSIan Lepore	[Nn][Oo] | [Nn][Oo][Nn][Ee] )
38735c001bSIan Lepore		return 0;;
39735c001bSIan Lepore	* )
40735c001bSIan Lepore		return 1;;
41735c001bSIan Lepore	esac
42735c001bSIan Lepore}
43735c001bSIan Lepore
440696600cSBjoern A. Zeebcan_run_nonroot()
450696600cSBjoern A. Zeeb{
460696600cSBjoern A. Zeeb	# If the admin set what uid to use, we don't change it.
470696600cSBjoern A. Zeeb	if [ -n "${ntpd_user}" ]; then
480696600cSBjoern A. Zeeb		return 1
490696600cSBjoern A. Zeeb	fi
500696600cSBjoern A. Zeeb
510696600cSBjoern A. Zeeb	# If the admin set any command line options involving files, we
520696600cSBjoern A. Zeeb	# may not be able to access them as user ntpd.
530696600cSBjoern A. Zeeb	case "${rc_flags}" in
540696600cSBjoern A. Zeeb	    *-f* | *--driftfile* | *-i* | *--jaildir*   | \
550696600cSBjoern A. Zeeb	    *-k* | *--keyfile*   | *-l* | *--logfile*   | \
560696600cSBjoern A. Zeeb	    *-p* | *--pidfile*   | *-s* | *--statsdir* )
570696600cSBjoern A. Zeeb		return 1;;
580696600cSBjoern A. Zeeb	esac
590696600cSBjoern A. Zeeb
600696600cSBjoern A. Zeeb	# If the admin set any options in ntp.conf involving files,
610696600cSBjoern A. Zeeb	# we may not be able to access them as user ntpd.
620696600cSBjoern A. Zeeb	local fileopts="^[ \t]*crypto|^[ \t]*driftfile|^[ \t]*key|^[ \t]*logfile|^[ \t]*statsdir"
630696600cSBjoern A. Zeeb	grep -E -q "${fileopts}" "${ntpd_config}" && return 1
640696600cSBjoern A. Zeeb
657ed279f5SGordon Bergling	# Try to set up the MAC ntpd policy so ntpd can run with reduced
660696600cSBjoern A. Zeeb	# privileges.  Detect whether MAC is compiled into the kernel, load
670696600cSBjoern A. Zeeb	# the policy module if not already present, then check whether the
680696600cSBjoern A. Zeeb	# policy has been disabled via tunable or sysctl.
690696600cSBjoern A. Zeeb	[ -n "$(sysctl -qn security.mac.version)" ] || return 1
700696600cSBjoern A. Zeeb	sysctl -qn security.mac.ntpd >/dev/null || kldload -qn mac_ntpd || return 1
710696600cSBjoern A. Zeeb	[ "$(sysctl -qn security.mac.ntpd.enabled)" == "1" ] || return 1
720696600cSBjoern A. Zeeb
730696600cSBjoern A. Zeeb	# On older existing systems, the ntp dir may by owned by root, change
740696600cSBjoern A. Zeeb	# it to ntpd to give the daemon create/write access to the driftfile.
750696600cSBjoern A. Zeeb	if [ "$(stat -f %u ${_ntp_default_dir})" = "0" ]; then
760696600cSBjoern A. Zeeb		chown ntpd:ntpd "${_ntp_default_dir}" || return 1
770696600cSBjoern A. Zeeb		chmod 0755 "${_ntp_default_dir}" || return 1
780696600cSBjoern A. Zeeb		logger -s -t "rc.d/ntpd" -p daemon.notice \
790696600cSBjoern A. Zeeb		    "${_ntp_default_dir} updated to owner ntpd:ntpd, mode 0755"
800696600cSBjoern A. Zeeb	fi
810696600cSBjoern A. Zeeb
820696600cSBjoern A. Zeeb	# If the driftfile exists in the standard location for older existing
830696600cSBjoern A. Zeeb	# systems, move it into the ntp dir and fix the ownership if we can.
840696600cSBjoern A. Zeeb	if [ -f "${_ntp_old_driftfile}" ] && [ ! -L "${_ntp_old_driftfile}" ]; then
850696600cSBjoern A. Zeeb		mv "${_ntp_old_driftfile}" "${_ntp_default_driftfile}" &&
860696600cSBjoern A. Zeeb		   chown ntpd:ntpd "${_ntp_default_driftfile}" || return 1
870696600cSBjoern A. Zeeb		logger -s -t "rc.d/ntpd" -p daemon.notice \
880696600cSBjoern A. Zeeb		    "${_ntp_default_driftfile} updated to owner ntpd:ntpd"
890696600cSBjoern A. Zeeb		logger -s -t "rc.d/ntpd" -p daemon.notice \
900696600cSBjoern A. Zeeb		    "${_ntp_old_driftfile} moved to ${_ntp_default_driftfile}"
910696600cSBjoern A. Zeeb	fi
920696600cSBjoern A. Zeeb}
930696600cSBjoern A. Zeeb
940696600cSBjoern A. Zeebntpd_precmd()
950696600cSBjoern A. Zeeb{
960696600cSBjoern A. Zeeb	local driftopt
970696600cSBjoern A. Zeeb
980696600cSBjoern A. Zeeb	# If we can run as a non-root user, switch uid to ntpd and use the
990696600cSBjoern A. Zeeb	# new default location for the driftfile inside the ntpd-owned dir.
1000696600cSBjoern A. Zeeb	# Otherwise, figure out what to do about the driftfile option.  If set
1010696600cSBjoern A. Zeeb	# by the admin, we don't add the option.  If the file exists in the old
1020696600cSBjoern A. Zeeb	# default location we use that, else we use the new default location.
1030696600cSBjoern A. Zeeb	if can_run_nonroot; then
1040696600cSBjoern A. Zeeb		_user="ntpd"
1050696600cSBjoern A. Zeeb		driftopt="-f ${_ntp_default_driftfile}"
106a2119d62SIan Lepore	elif grep -q "^[ \t]*driftfile" "${ntpd_config}" ||
107a2119d62SIan Lepore	     [ -n "${rc_flags}" ] &&
108a2119d62SIan Lepore	     ( [ -z "${rc_flags##*-f*}" ] ||
109a2119d62SIan Lepore	       [ -z "${rc_flags##*--driftfile*}" ] ); then
1100696600cSBjoern A. Zeeb		driftopt="" # admin set the option, we don't need to add it.
1110696600cSBjoern A. Zeeb	elif [ -f "${_ntp_old_driftfile}" ]; then
1120696600cSBjoern A. Zeeb		driftopt="-f ${_ntp_old_driftfile}"
1130696600cSBjoern A. Zeeb	else
1140696600cSBjoern A. Zeeb		driftopt="-f ${_ntp_default_driftfile}"
1150696600cSBjoern A. Zeeb	fi
1160696600cSBjoern A. Zeeb
1170696600cSBjoern A. Zeeb	# Set command_args based on the various config vars.
1180696600cSBjoern A. Zeeb	command_args="-p ${pidfile} -c ${ntpd_config} ${driftopt}"
1190696600cSBjoern A. Zeeb	if checkyesno ntpd_sync_on_start; then
1200696600cSBjoern A. Zeeb		command_args="${command_args} -g"
1210696600cSBjoern A. Zeeb	fi
1220696600cSBjoern A. Zeeb
123735c001bSIan Lepore	# Make sure the leapfile is ready to use, unless leapfile
124735c001bSIan Lepore	# handling is disabled.
125735c001bSIan Lepore	if leapfile_is_disabled; then
126735c001bSIan Lepore		return
127735c001bSIan Lepore	fi
128735c001bSIan Lepore
1290696600cSBjoern A. Zeeb	ntpd_init_leapfile
1300696600cSBjoern A. Zeeb	if [ ! -f "${ntp_db_leapfile}" ]; then
1310696600cSBjoern A. Zeeb		ntpd_fetch_leapfile
1320696600cSBjoern A. Zeeb	fi
1330696600cSBjoern A. Zeeb}
1340696600cSBjoern A. Zeeb
1350696600cSBjoern A. Zeebcurrent_ntp_ts() {
1360696600cSBjoern A. Zeeb	# Seconds between 1900-01-01 and 1970-01-01
1370696600cSBjoern A. Zeeb	# echo $(((70*365+17)*86400))
1380696600cSBjoern A. Zeeb	ntp_to_unix=2208988800
1390696600cSBjoern A. Zeeb
1400696600cSBjoern A. Zeeb	echo $(($(date -u +%s)+$ntp_to_unix))
1410696600cSBjoern A. Zeeb}
1420696600cSBjoern A. Zeeb
1430696600cSBjoern A. Zeebget_ntp_leapfile_ver() {
1440696600cSBjoern A. Zeeb	# Leapfile update date (version number).
1450696600cSBjoern A. Zeeb	expr "$(awk '$1 == "#$" { print $2 }' "$1" 2>/dev/null)" : \
1460696600cSBjoern A. Zeeb		'^\([1-9][0-9]*\)$' \| 0
1470696600cSBjoern A. Zeeb}
1480696600cSBjoern A. Zeeb
1490696600cSBjoern A. Zeebget_ntp_leapfile_expiry() {
1500696600cSBjoern A. Zeeb	# Leapfile expiry date.
1510696600cSBjoern A. Zeeb	expr "$(awk '$1 == "#@" { print $2 }' "$1" 2>/dev/null)" : \
1520696600cSBjoern A. Zeeb		'^\([1-9][0-9]*\)$' \| 0
1530696600cSBjoern A. Zeeb}
1540696600cSBjoern A. Zeeb
1550696600cSBjoern A. Zeebntpd_init_leapfile() {
156735c001bSIan Lepore
157735c001bSIan Lepore	if leapfile_is_disabled; then
158735c001bSIan Lepore		return
159735c001bSIan Lepore	fi
160735c001bSIan Lepore
1610696600cSBjoern A. Zeeb	# Refresh working leapfile with an invalid hash due to
1620696600cSBjoern A. Zeeb	# FreeBSD id header. Ntpd will ignore leapfiles with a
1630696600cSBjoern A. Zeeb	# mismatch hash. The file must be the virgin file from
1640696600cSBjoern A. Zeeb	# the source.
1650696600cSBjoern A. Zeeb	if [ ! -f $ntp_db_leapfile ]; then
1660696600cSBjoern A. Zeeb		cp -p $ntp_src_leapfile $ntp_db_leapfile
1670696600cSBjoern A. Zeeb	fi
1680696600cSBjoern A. Zeeb}
1690696600cSBjoern A. Zeeb
1700696600cSBjoern A. Zeebntpd_needfetch_leapfile() {
1710696600cSBjoern A. Zeeb	local rc verbose
1720696600cSBjoern A. Zeeb
173735c001bSIan Lepore	if leapfile_is_disabled; then
174735c001bSIan Lepore		# Return code 1: ntp leapfile fetch not needed
175735c001bSIan Lepore		return 1
176735c001bSIan Lepore	fi
177735c001bSIan Lepore
1780696600cSBjoern A. Zeeb	if checkyesno ntp_leapfile_fetch_verbose; then
1790696600cSBjoern A. Zeeb		verbose=echo
1800696600cSBjoern A. Zeeb	else
1810696600cSBjoern A. Zeeb		verbose=:
1820696600cSBjoern A. Zeeb	fi
1830696600cSBjoern A. Zeeb
1840696600cSBjoern A. Zeeb	ntp_ver_no_src=$(get_ntp_leapfile_ver $ntp_src_leapfile)
1850696600cSBjoern A. Zeeb	ntp_expiry_src=$(get_ntp_leapfile_expiry $ntp_src_leapfile)
1860696600cSBjoern A. Zeeb	ntp_ver_no_db=$(get_ntp_leapfile_ver $ntp_db_leapfile)
1870696600cSBjoern A. Zeeb	ntp_expiry_db=$(get_ntp_leapfile_expiry $ntp_db_leapfile)
1880696600cSBjoern A. Zeeb	$verbose ntp_src_leapfile version is $ntp_ver_no_src expires $ntp_expiry_src
1890696600cSBjoern A. Zeeb	$verbose ntp_db_leapfile version is $ntp_ver_no_db expires $ntp_expiry_db
1900696600cSBjoern A. Zeeb
1910696600cSBjoern A. Zeeb	if [ "$ntp_ver_no_src" -gt "$ntp_ver_no_db" -o \
1920696600cSBjoern A. Zeeb	     "$ntp_ver_no_src" -eq "$ntp_ver_no_db" -a \
1930696600cSBjoern A. Zeeb	     "$ntp_expiry_src" -gt "$ntp_expiry_db" ]; then
1940696600cSBjoern A. Zeeb		$verbose replacing $ntp_db_leapfile with $ntp_src_leapfile
1950696600cSBjoern A. Zeeb		cp -p $ntp_src_leapfile $ntp_db_leapfile
1960696600cSBjoern A. Zeeb		ntp_ver_no_db=$ntp_ver_no_src
1970696600cSBjoern A. Zeeb	else
1980696600cSBjoern A. Zeeb		$verbose not replacing $ntp_db_leapfile with $ntp_src_leapfile
1990696600cSBjoern A. Zeeb	fi
2000696600cSBjoern A. Zeeb	ntp_leapfile_expiry_seconds=$((ntp_leapfile_expiry_days*86400))
2010696600cSBjoern A. Zeeb	ntp_leap_expiry=$(get_ntp_leapfile_expiry $ntp_db_leapfile)
2020696600cSBjoern A. Zeeb	ntp_leap_fetch_date=$((ntp_leap_expiry-ntp_leapfile_expiry_seconds))
2030696600cSBjoern A. Zeeb	if [ $(current_ntp_ts) -ge $ntp_leap_fetch_date ]; then
2040696600cSBjoern A. Zeeb		$verbose Within ntp leapfile expiry limit, initiating fetch
2050696600cSBjoern A. Zeeb		# Return code 0: ntp leapfile fetch needed
2060696600cSBjoern A. Zeeb		return 0
2070696600cSBjoern A. Zeeb	fi
2080696600cSBjoern A. Zeeb	# Return code 1: ntp leapfile fetch not needed
2090696600cSBjoern A. Zeeb	return 1
2100696600cSBjoern A. Zeeb}
2110696600cSBjoern A. Zeeb
2120696600cSBjoern A. Zeebntpd_fetch_leapfile() {
213735c001bSIan Lepore
214735c001bSIan Lepore	if leapfile_is_disabled; then
215735c001bSIan Lepore		return
216735c001bSIan Lepore	fi
217735c001bSIan Lepore
2180696600cSBjoern A. Zeeb	if checkyesno ntp_leapfile_fetch_verbose; then
2190696600cSBjoern A. Zeeb		verbose=echo
2200696600cSBjoern A. Zeeb	else
2210696600cSBjoern A. Zeeb		verbose=:
2220696600cSBjoern A. Zeeb	fi
2230696600cSBjoern A. Zeeb
2240696600cSBjoern A. Zeeb	if ntpd_needfetch_leapfile ; then
2250696600cSBjoern A. Zeeb		for url in $ntp_leapfile_sources ; do
2260696600cSBjoern A. Zeeb			$verbose fetching $url
227c6806434SCy Schubert			# Circumvent umask 027 and 077 in login.conf(5)
228c6806434SCy Schubert			umask 022
2290696600cSBjoern A. Zeeb			fetch $ntp_leapfile_fetch_opts -o $_ntp_tmp_leapfile $url && break
2300696600cSBjoern A. Zeeb		done
2310696600cSBjoern A. Zeeb		ntp_ver_no_tmp=$(get_ntp_leapfile_ver $_ntp_tmp_leapfile)
2320696600cSBjoern A. Zeeb		ntp_expiry_tmp=$(get_ntp_leapfile_expiry $_ntp_tmp_leapfile)
2330696600cSBjoern A. Zeeb		if [ "$ntp_expiry_tmp" -gt "$ntp_expiry_db" -o \
2340696600cSBjoern A. Zeeb		     "$ntp_expiry_tmp" -eq "$ntp_expiry_db" -a \
2350696600cSBjoern A. Zeeb		     "$ntp_ver_no_tmp" -gt "$ntp_ver_no_db" ]; then
2360696600cSBjoern A. Zeeb			$verbose using $url as $ntp_db_leapfile
2370696600cSBjoern A. Zeeb			mv -f $_ntp_tmp_leapfile $ntp_db_leapfile ||
2380696600cSBjoern A. Zeeb			    $verbose "warning: cannot replace $ntp_db_leapfile (read-only fs?)"
2390696600cSBjoern A. Zeeb		else
2400696600cSBjoern A. Zeeb			$verbose using existing $ntp_db_leapfile
2410696600cSBjoern A. Zeeb		fi
2420696600cSBjoern A. Zeeb	fi
2430696600cSBjoern A. Zeeb}
2440696600cSBjoern A. Zeeb
2451442fed7SJohn Baldwinntpd_resume()
2461442fed7SJohn Baldwin{
2471442fed7SJohn Baldwin	run_rc_command restart
2481442fed7SJohn Baldwin}
2491442fed7SJohn Baldwin
2500696600cSBjoern A. Zeebrun_rc_command "$1"
251