ntpd 7.17 KB
Newer Older
1
2
#!/bin/sh
#
3
# $FreeBSD$
4
5
6
#

# PROVIDE: ntpd
7
# REQUIRE: DAEMON ntpdate FILESYSTEMS devfs
8
# BEFORE:  LOGIN
9
# KEYWORD: nojail shutdown
10
11
12

. /etc/rc.subr

13
name="ntpd"
14
desc="Network Time Protocol daemon"
15
rcvar="ntpd_enable"
16
command="/usr/sbin/${name}"
17
extra_commands="fetch needfetch"
18
fetch_cmd="ntpd_fetch_leapfile"
19
needfetch_cmd="ntpd_needfetch_leapfile"
20
start_precmd="ntpd_precmd"
21

22
_ntp_tmp_leapfile="/var/run/ntpd.leap-seconds.list"
23
24
25
26
27
_ntp_default_dir="/var/db/ntp"
_ntp_default_driftfile="${_ntp_default_dir}/ntpd.drift"
_ntp_old_driftfile="/var/db/ntpd.drift"

pidfile="${_ntp_default_dir}/${name}.pid"
28

29
30
load_rc_config $name

Ian Lepore's avatar
Ian Lepore committed
31
32
33
34
35
36
37
38
39
40
leapfile_is_disabled() {
	# Return true (0) if automatic leapfile handling is disabled.
	case "$ntp_db_leapfile" in
	[Nn][Oo] | [Nn][Oo][Nn][Ee] )
		return 0;;
	* )
		return 1;;
	esac
}

41
can_run_nonroot()
42
{
43
44
45
	# If the admin set what uid to use, we don't change it.
	if [ -n "${ntpd_user}" ]; then
		return 1
46
47
	fi

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
	# If the admin set any command line options involving files, we
	# may not be able to access them as user ntpd.
	case "${rc_flags}" in
	    *-f* | *--driftfile* | *-i* | *--jaildir*   | \
	    *-k* | *--keyfile*   | *-l* | *--logfile*   | \
	    *-p* | *--pidfile*   | *-s* | *--statsdir* )
		return 1;;
	esac

	# If the admin set any options in ntp.conf involving files,
	# we may not be able to access them as user ntpd.
	local fileopts="^[ \t]*crypto|^[ \t]*driftfile|^[ \t]*key|^[ \t]*logfile|^[ \t]*statsdir"
	grep -E -q "${fileopts}" "${ntpd_config}" && return 1

	# Try to set up the the MAC ntpd policy so ntpd can run with reduced
	# privileges.  Detect whether MAC is compiled into the kernel, load
	# the policy module if not already present, then check whether the
	# policy has been disabled via tunable or sysctl.
	[ -n "$(sysctl -qn security.mac.version)" ] || return 1
	sysctl -qn security.mac.ntpd >/dev/null || kldload -qn mac_ntpd || return 1
	[ "$(sysctl -qn security.mac.ntpd.enabled)" == "1" ] || return 1

	# On older existing systems, the ntp dir may by owned by root, change
	# it to ntpd to give the daemon create/write access to the driftfile.
	if [ "$(stat -f %u ${_ntp_default_dir})" = "0" ]; then
		chown ntpd:ntpd "${_ntp_default_dir}" || return 1
		chmod 0755 "${_ntp_default_dir}" || return 1
		logger -s -t "rc.d/ntpd" -p daemon.notice \
		    "${_ntp_default_dir} updated to owner ntpd:ntpd, mode 0755"
	fi
78

79
80
81
82
83
84
85
86
87
	# If the driftfile exists in the standard location for older existing
	# systems, move it into the ntp dir and fix the ownership if we can.
	if [ -f "${_ntp_old_driftfile}" ] && [ ! -L "${_ntp_old_driftfile}" ]; then
		mv "${_ntp_old_driftfile}" "${_ntp_default_driftfile}" &&
		   chown ntpd:ntpd "${_ntp_default_driftfile}" || return 1
		logger -s -t "rc.d/ntpd" -p daemon.notice \
		    "${_ntp_default_driftfile} updated to owner ntpd:ntpd"
		logger -s -t "rc.d/ntpd" -p daemon.notice \
		    "${_ntp_old_driftfile} moved to ${_ntp_default_driftfile}"
88
	fi
89
}
90

91
92
93
94
95
96
97
98
99
100
101
102
ntpd_precmd()
{
	local driftopt

	# If we can run as a non-root user, switch uid to ntpd and use the
	# new default location for the driftfile inside the ntpd-owned dir.
	# Otherwise, figure out what to do about the driftfile option.  If set
	# by the admin, we don't add the option.  If the file exists in the old
	# default location we use that, else we use the new default location.
	if can_run_nonroot; then
		_user="ntpd"
		driftopt="-f ${_ntp_default_driftfile}"
Ian Lepore's avatar
Ian Lepore committed
103
104
105
106
	elif grep -q "^[ \t]*driftfile" "${ntpd_config}" ||
	     [ -n "${rc_flags}" ] &&
	     ( [ -z "${rc_flags##*-f*}" ] ||
	       [ -z "${rc_flags##*--driftfile*}" ] ); then
107
108
109
110
111
		driftopt="" # admin set the option, we don't need to add it.
	elif [ -f "${_ntp_old_driftfile}" ]; then
		driftopt="-f ${_ntp_old_driftfile}"
	else
		driftopt="-f ${_ntp_default_driftfile}"
112
113
	fi

114
115
116
117
	# Set command_args based on the various config vars.
	command_args="-p ${pidfile} -c ${ntpd_config} ${driftopt}"
	if checkyesno ntpd_sync_on_start; then
		command_args="${command_args} -g"
118
119
	fi

Ian Lepore's avatar
Ian Lepore committed
120
121
122
123
124
125
	# Make sure the leapfile is ready to use, unless leapfile
	# handling is disabled.
	if leapfile_is_disabled; then
		return
	fi

126
127
128
129
	ntpd_init_leapfile
	if [ ! -f "${ntp_db_leapfile}" ]; then
		ntpd_fetch_leapfile
	fi
130
131
}

132
133
134
135
136
137
138
139
140
current_ntp_ts() {
	# Seconds between 1900-01-01 and 1970-01-01
	# echo $(((70*365+17)*86400))
	ntp_to_unix=2208988800

	echo $(($(date -u +%s)+$ntp_to_unix))
}
	
get_ntp_leapfile_ver() {
141
	# Leapfile update date (version number).
142
143
144
145
146
	expr "$(awk '$1 == "#$" { print $2 }' "$1" 2>/dev/null)" : \
		'^\([1-9][0-9]*\)$' \| 0
}

get_ntp_leapfile_expiry() {
147
	# Leapfile expiry date.
148
149
150
151
	expr "$(awk '$1 == "#@" { print $2 }' "$1" 2>/dev/null)" : \
		'^\([1-9][0-9]*\)$' \| 0
}

152
ntpd_init_leapfile() {
Ian Lepore's avatar
Ian Lepore committed
153
154
155
156
157

	if leapfile_is_disabled; then
		return
	fi

158
159
160
161
	# Refresh working leapfile with an invalid hash due to
	# FreeBSD id header. Ntpd will ignore leapfiles with a
	# mismatch hash. The file must be the virgin file from
	# the source.
162
	if [ ! -f $ntp_db_leapfile ]; then
163
164
165
166
		cp -p $ntp_src_leapfile $ntp_db_leapfile
	fi
}

167
ntpd_needfetch_leapfile() {
168
	local rc verbose
Ian Lepore's avatar
Ian Lepore committed
169
170
171
172
173
174

	if leapfile_is_disabled; then
		# Return code 1: ntp leapfile fetch not needed
		return 1
	fi

175
176
177
178
179
180
181
	if checkyesno ntp_leapfile_fetch_verbose; then
		verbose=echo
	else
		verbose=:
	fi

	ntp_ver_no_src=$(get_ntp_leapfile_ver $ntp_src_leapfile)
182
	ntp_expiry_src=$(get_ntp_leapfile_expiry $ntp_src_leapfile)
183
	ntp_ver_no_db=$(get_ntp_leapfile_ver $ntp_db_leapfile)
184
	ntp_expiry_db=$(get_ntp_leapfile_expiry $ntp_db_leapfile)
185
186
	$verbose ntp_src_leapfile version is $ntp_ver_no_src expires $ntp_expiry_src
	$verbose ntp_db_leapfile version is $ntp_ver_no_db expires $ntp_expiry_db
187

188
189
190
	if [ "$ntp_ver_no_src" -gt "$ntp_ver_no_db" -o \
	     "$ntp_ver_no_src" -eq "$ntp_ver_no_db" -a \
	     "$ntp_expiry_src" -gt "$ntp_expiry_db" ]; then
191
192
193
194
195
196
197
		$verbose replacing $ntp_db_leapfile with $ntp_src_leapfile 
		cp -p $ntp_src_leapfile $ntp_db_leapfile
		ntp_ver_no_db=$ntp_ver_no_src
	else
		$verbose not replacing $ntp_db_leapfile with $ntp_src_leapfile 
	fi
	ntp_leapfile_expiry_seconds=$((ntp_leapfile_expiry_days*86400))
198
	ntp_leap_expiry=$(get_ntp_leapfile_expiry $ntp_db_leapfile)
199
200
201
	ntp_leap_fetch_date=$((ntp_leap_expiry-ntp_leapfile_expiry_seconds))
	if [ $(current_ntp_ts) -ge $ntp_leap_fetch_date ]; then
		$verbose Within ntp leapfile expiry limit, initiating fetch
202
203
204
205
206
207
208
209
		# Return code 0: ntp leapfile fetch needed
		return 0
	fi
	# Return code 1: ntp leapfile fetch not needed
	return 1
}

ntpd_fetch_leapfile() {
Ian Lepore's avatar
Ian Lepore committed
210
211
212
213
214

	if leapfile_is_disabled; then
		return
	fi

215
216
217
218
219
220
221
	if checkyesno ntp_leapfile_fetch_verbose; then
		verbose=echo
	else
		verbose=:
	fi

	if ntpd_needfetch_leapfile ; then
222
223
		for url in $ntp_leapfile_sources ; do
			$verbose fetching $url
224
225
			# Circumvent umask 027 and 077 in login.conf(5)
			umask 022
226
			fetch $ntp_leapfile_fetch_opts -o $_ntp_tmp_leapfile $url && break
227
		done
228
229
		ntp_ver_no_tmp=$(get_ntp_leapfile_ver $_ntp_tmp_leapfile)
		ntp_expiry_tmp=$(get_ntp_leapfile_expiry $_ntp_tmp_leapfile)
230
231
232
		if [ "$ntp_expiry_tmp" -gt "$ntp_expiry_db" -o \
		     "$ntp_expiry_tmp" -eq "$ntp_expiry_db" -a \
		     "$ntp_ver_no_tmp" -gt "$ntp_ver_no_db" ]; then
233
			$verbose using $url as $ntp_db_leapfile
234
			mv -f $_ntp_tmp_leapfile $ntp_db_leapfile ||
235
			    $verbose "warning: cannot replace $ntp_db_leapfile (read-only fs?)"
236
237
238
239
240
241
		else
			$verbose using existing $ntp_db_leapfile
		fi
	fi
}

242
run_rc_command "$1"