6 # REQUIRE: DAEMON ntpdate FILESYSTEMS devfs
8 # KEYWORD: nojail resume shutdown
13 desc="Network Time Protocol daemon"
15 command="/usr/sbin/${name}"
16 extra_commands="fetch needfetch resume"
17 fetch_cmd="ntpd_fetch_leapfile"
18 needfetch_cmd="ntpd_needfetch_leapfile"
19 resume_cmd="ntpd_resume"
20 start_precmd="ntpd_precmd"
22 _ntp_tmp_leapfile="/var/run/ntpd.leap-seconds.list"
23 _ntp_default_dir="/var/db/ntp"
24 _ntp_default_driftfile="${_ntp_default_dir}/ntpd.drift"
25 _ntp_old_driftfile="/var/db/ntpd.drift"
27 pidfile="${_ntp_default_dir}/${name}.pid"
31 leapfile_is_disabled() {
32 # Return true (0) if automatic leapfile handling is disabled.
33 case "$ntp_db_leapfile" in
34 [Nn][Oo] | [Nn][Oo][Nn][Ee] )
43 # If the admin set what uid to use, we don't change it.
44 if [ -n "${ntpd_user}" ]; then
48 # If the admin set any command line options involving files, we
49 # may not be able to access them as user ntpd.
51 *-f* | *--driftfile* | *-i* | *--jaildir* | \
52 *-k* | *--keyfile* | *-l* | *--logfile* | \
53 *-p* | *--pidfile* | *-s* | *--statsdir* )
57 # If the admin set any options in ntp.conf involving files,
58 # we may not be able to access them as user ntpd.
59 local fileopts="^[ \t]*crypto|^[ \t]*driftfile|^[ \t]*key|^[ \t]*logfile|^[ \t]*statsdir"
60 grep -E -q "${fileopts}" "${ntpd_config}" && return 1
62 # Try to set up the MAC ntpd policy so ntpd can run with reduced
63 # privileges. Detect whether MAC is compiled into the kernel, load
64 # the policy module if not already present, then check whether the
65 # policy has been disabled via tunable or sysctl.
66 [ -n "$(sysctl -qn security.mac.version)" ] || return 1
67 sysctl -qn security.mac.ntpd >/dev/null || kldload -qn mac_ntpd || return 1
68 [ "$(sysctl -qn security.mac.ntpd.enabled)" == "1" ] || return 1
70 # On older existing systems, the ntp dir may by owned by root, change
71 # it to ntpd to give the daemon create/write access to the driftfile.
72 if [ "$(stat -f %u ${_ntp_default_dir})" = "0" ]; then
73 chown ntpd:ntpd "${_ntp_default_dir}" || return 1
74 chmod 0755 "${_ntp_default_dir}" || return 1
75 logger -s -t "rc.d/ntpd" -p daemon.notice \
76 "${_ntp_default_dir} updated to owner ntpd:ntpd, mode 0755"
79 # If the driftfile exists in the standard location for older existing
80 # systems, move it into the ntp dir and fix the ownership if we can.
81 if [ -f "${_ntp_old_driftfile}" ] && [ ! -L "${_ntp_old_driftfile}" ]; then
82 mv "${_ntp_old_driftfile}" "${_ntp_default_driftfile}" &&
83 chown ntpd:ntpd "${_ntp_default_driftfile}" || return 1
84 logger -s -t "rc.d/ntpd" -p daemon.notice \
85 "${_ntp_default_driftfile} updated to owner ntpd:ntpd"
86 logger -s -t "rc.d/ntpd" -p daemon.notice \
87 "${_ntp_old_driftfile} moved to ${_ntp_default_driftfile}"
95 # If we can run as a non-root user, switch uid to ntpd and use the
96 # new default location for the driftfile inside the ntpd-owned dir.
97 # Otherwise, figure out what to do about the driftfile option. If set
98 # by the admin, we don't add the option. If the file exists in the old
99 # default location we use that, else we use the new default location.
100 if can_run_nonroot; then
102 driftopt="-f ${_ntp_default_driftfile}"
103 elif grep -q "^[ \t]*driftfile" "${ntpd_config}" ||
104 [ -n "${rc_flags}" ] &&
105 ( [ -z "${rc_flags##*-f*}" ] ||
106 [ -z "${rc_flags##*--driftfile*}" ] ); then
107 driftopt="" # admin set the option, we don't need to add it.
108 elif [ -f "${_ntp_old_driftfile}" ]; then
109 driftopt="-f ${_ntp_old_driftfile}"
111 driftopt="-f ${_ntp_default_driftfile}"
114 # Set command_args based on the various config vars.
115 command_args="-p ${pidfile} -c ${ntpd_config} ${driftopt}"
116 if checkyesno ntpd_sync_on_start; then
117 command_args="${command_args} -g"
120 # Make sure the leapfile is ready to use, unless leapfile
121 # handling is disabled.
122 if leapfile_is_disabled; then
127 if [ ! -f "${ntp_db_leapfile}" ]; then
133 # Seconds between 1900-01-01 and 1970-01-01
134 # echo $(((70*365+17)*86400))
135 ntp_to_unix=2208988800
137 echo $(($(date -u +%s)+$ntp_to_unix))
140 get_ntp_leapfile_ver() {
141 # Leapfile update date (version number).
142 expr "$(awk '$1 == "#$" { print $2 }' "$1" 2>/dev/null)" : \
143 '^\([1-9][0-9]*\)$' \| 0
146 get_ntp_leapfile_expiry() {
147 # Leapfile expiry date.
148 expr "$(awk '$1 == "#@" { print $2 }' "$1" 2>/dev/null)" : \
149 '^\([1-9][0-9]*\)$' \| 0
152 ntpd_init_leapfile() {
154 if leapfile_is_disabled; then
158 # Refresh working leapfile with an invalid hash due to
159 # FreeBSD id header. Ntpd will ignore leapfiles with a
160 # mismatch hash. The file must be the virgin file from
162 if [ ! -f $ntp_db_leapfile ]; then
163 cp -p $ntp_src_leapfile $ntp_db_leapfile
167 ntpd_needfetch_leapfile() {
170 if leapfile_is_disabled; then
171 # Return code 1: ntp leapfile fetch not needed
175 if checkyesno ntp_leapfile_fetch_verbose; then
181 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 $verbose ntp_src_leapfile version is $ntp_ver_no_src expires $ntp_expiry_src
186 $verbose ntp_db_leapfile version is $ntp_ver_no_db expires $ntp_expiry_db
188 if [ "$ntp_ver_no_src" -gt "$ntp_ver_no_db" -o \
189 "$ntp_ver_no_src" -eq "$ntp_ver_no_db" -a \
190 "$ntp_expiry_src" -gt "$ntp_expiry_db" ]; then
191 $verbose replacing $ntp_db_leapfile with $ntp_src_leapfile
192 cp -p $ntp_src_leapfile $ntp_db_leapfile
193 ntp_ver_no_db=$ntp_ver_no_src
195 $verbose not replacing $ntp_db_leapfile with $ntp_src_leapfile
197 ntp_leapfile_expiry_seconds=$((ntp_leapfile_expiry_days*86400))
198 ntp_leap_expiry=$(get_ntp_leapfile_expiry $ntp_db_leapfile)
199 ntp_leap_fetch_date=$((ntp_leap_expiry-ntp_leapfile_expiry_seconds))
200 if [ $(current_ntp_ts) -ge $ntp_leap_fetch_date ]; then
201 $verbose Within ntp leapfile expiry limit, initiating fetch
202 # Return code 0: ntp leapfile fetch needed
205 # Return code 1: ntp leapfile fetch not needed
209 ntpd_fetch_leapfile() {
211 if leapfile_is_disabled; then
215 if checkyesno ntp_leapfile_fetch_verbose; then
221 if ntpd_needfetch_leapfile ; then
222 for url in $ntp_leapfile_sources ; do
223 $verbose fetching $url
224 # Circumvent umask 027 and 077 in login.conf(5)
226 fetch $ntp_leapfile_fetch_opts -o $_ntp_tmp_leapfile $url && break
228 ntp_ver_no_tmp=$(get_ntp_leapfile_ver $_ntp_tmp_leapfile)
229 ntp_expiry_tmp=$(get_ntp_leapfile_expiry $_ntp_tmp_leapfile)
230 if [ "$ntp_expiry_tmp" -gt "$ntp_expiry_db" -o \
231 "$ntp_expiry_tmp" -eq "$ntp_expiry_db" -a \
232 "$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?)"
237 $verbose using existing $ntp_db_leapfile
244 run_rc_command restart