Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf +++ etc/defaults/rc.conf @@ -381,8 +381,7 @@ ntpd_program="/usr/sbin/ntpd" # path to ntpd, if you want a different one. ntpd_config="/etc/ntp.conf" # ntpd(8) configuration file ntpd_sync_on_start="NO" # Sync time on ntpd startup, even if offset is high -ntpd_flags="-p /var/run/ntpd.pid -f /var/db/ntpd.drift" - # Flags to ntpd (if enabled). +ntpd_flags="" # Additional flags to ntpd ntp_src_leapfile="/etc/ntp/leap-seconds" # Initial source for ntpd leapfile ntp_db_leapfile="/var/db/ntpd.leap-seconds.list" Index: etc/rc.d/ntpd =================================================================== --- etc/rc.d/ntpd +++ etc/rc.d/ntpd @@ -14,53 +14,99 @@ desc="Network Time Protocol daemon" rcvar="ntpd_enable" command="/usr/sbin/${name}" -pidfile="/var/run/${name}.pid" extra_commands="fetch needfetch" fetch_cmd="ntpd_fetch_leapfile" needfetch_cmd="ntpd_needfetch_leapfile" start_precmd="ntpd_precmd" _ntp_tmp_leapfile="/var/run/ntpd.leap-seconds.list" +_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" load_rc_config $name -ntpd_precmd() +can_run_nonroot() { - rc_flags="-c ${ntpd_config} ${ntpd_flags}" + # If the admin set what uid to use, we don't change it. + if [ -n "${ntpd_user}" ]; then + return 1 + fi + + # 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. + if [ -n "$(sysctl -qn security.mac.version)" ]; then + sysctl -qn security.mac.ntpd >/dev/null || kldload -qn mac_ntpd || return 1 + if [ "$(sysctl -qn security.mac.ntpd.enabled)" != "1" ]; then + return 1 + fi + fi - if checkyesno ntpd_sync_on_start; then - rc_flags="-g $rc_flags" + # 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 fi - ntpd_init_leapfile + # 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 + fi +} - if [ ! -f $ntp_db_leapfile ]; then - ntpd_fetch_leapfile +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}" + elif [ -z "${rc_flags##*-f*}" ] || + [ -z "${rc_flags##*--driftfile*}" ] || + grep -q "^[ \t]*driftfile" "${ntpd_config}" + 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}" fi - if [ -z "$ntpd_chrootdir" ]; then - return 0; + # 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" fi - # If running in a chroot cage, ensure that the appropriate files - # exist inside the cage, as well as helper symlinks into the cage - # from outside. - # - # As this is called after the is_running and required_dir checks - # are made in run_rc_command(), we can safely assume ${ntpd_chrootdir} - # exists and ntpd isn't running at this point (unless forcestart - # is used). - # - if [ ! -c "${ntpd_chrootdir}/dev/clockctl" ]; then - rm -f "${ntpd_chrootdir}/dev/clockctl" - ( cd /dev ; /bin/pax -rw -pe clockctl "${ntpd_chrootdir}/dev" ) - fi - ln -fs "${ntpd_chrootdir}/var/db/ntp.drift" /var/db/ntp.drift - ln -fs "${ntpd_chrootdir}${_ntp_tmp_leapfile}" ${_ntp_tmp_leapfile} - - # Change run_rc_commands()'s internal copy of $ntpd_flags - # - rc_flags="-u ntpd:ntpd -i ${ntpd_chrootdir} $rc_flags" + # Make sure the leapfile is ready to use. + ntpd_init_leapfile + if [ ! -f "${ntp_db_leapfile}" ]; then + ntpd_fetch_leapfile + fi } current_ntp_ts() {