sys_netbsd: allow running without root privileges

On NetBSD programs with write access to /dev/clockctl can adjust or set
the system clock without the root privileges. Add a function to drop the
privileges and check if the process has write access to the device to
get a more descriptive error message when the chrony uid/gid doesn't
match the owner of the device.
This commit is contained in:
Miroslav Lichvar 2015-08-25 12:15:58 +02:00
parent 8854c00d48
commit 7b6435b2b8
4 changed files with 36 additions and 0 deletions

8
configure vendored
View file

@ -215,6 +215,7 @@ feat_rtc=1
try_rtc=0 try_rtc=0
feat_droproot=1 feat_droproot=1
try_libcap=0 try_libcap=0
try_clockctl=0
readline_lib="" readline_lib=""
readline_inc="" readline_inc=""
ncurses_lib="" ncurses_lib=""
@ -405,6 +406,7 @@ case $SYSTEM in
NetBSD-* ) NetBSD-* )
EXTRA_OBJECTS="sys_netbsd.o" EXTRA_OBJECTS="sys_netbsd.o"
EXTRA_LIBS="-lkvm" EXTRA_LIBS="-lkvm"
try_clockctl=1
add_def NETBSD add_def NETBSD
echo "Configuring for $SYSTEM" echo "Configuring for $SYSTEM"
;; ;;
@ -590,6 +592,12 @@ then
EXTRA_LIBS="$EXTRA_LIBS -lcap" EXTRA_LIBS="$EXTRA_LIBS -lcap"
fi fi
if [ $feat_droproot = "1" ] && [ $try_clockctl = "1" ] && \
test_code '<sys/clockctl.h>' 'sys/clockctl.h' '' '' ''
then
add_def FEAT_PRIVDROP
fi
if [ $feat_rtc = "1" ] && [ $try_rtc = "1" ] && \ if [ $feat_rtc = "1" ] && [ $try_rtc = "1" ] && \
test_code '<linux/rtc.h>' 'sys/ioctl.h linux/rtc.h' '' '' \ test_code '<linux/rtc.h>' 'sys/ioctl.h linux/rtc.h' '' '' \
'ioctl(1, RTC_UIE_ON&RTC_UIE_OFF&RTC_RD_TIME&RTC_SET_TIME, 0&RTC_UF);' 'ioctl(1, RTC_UIE_ON&RTC_UIE_OFF&RTC_RD_TIME&RTC_SET_TIME, 0&RTC_UF);'

2
sys.c
View file

@ -113,6 +113,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid)
{ {
#if defined(LINUX) && defined (FEAT_PRIVDROP) #if defined(LINUX) && defined (FEAT_PRIVDROP)
SYS_Linux_DropRoot(uid, gid); SYS_Linux_DropRoot(uid, gid);
#elif defined(NETBSD) && defined(FEAT_PRIVDROP)
SYS_NetBSD_DropRoot(uid, gid);
#else #else
LOG_FATAL(LOGF_Sys, "dropping root privileges not supported"); LOG_FATAL(LOGF_Sys, "dropping root privileges not supported");
#endif #endif

View file

@ -324,5 +324,29 @@ SYS_NetBSD_Finalise(void)
/* ================================================== */ /* ================================================== */
#ifdef FEAT_PRIVDROP
void
SYS_NetBSD_DropRoot(uid_t uid, gid_t gid)
{
int fd;
if (setgroups(0, NULL))
LOG_FATAL(LOGF_SysNetBSD, "setgroups() failed : %s", strerror(errno));
if (setgid(gid))
LOG_FATAL(LOGF_SysNetBSD, "setgid(%d) failed : %s", gid, strerror(errno));
if (setuid(uid))
LOG_FATAL(LOGF_SysNetBSD, "setuid(%d) failed : %s", uid, strerror(errno));
DEBUG_LOG(LOGF_SysNetBSD, "Root dropped to uid %d gid %d", uid, gid);
/* Check if we have write access to /dev/clockctl */
fd = open("/dev/clockctl", O_WRONLY);
if (fd < 0)
LOG_FATAL(LOGF_SysNetBSD, "Can't write to /dev/clockctl");
close(fd);
}
#endif
#endif /* NETBSD */ #endif /* NETBSD */

View file

@ -32,4 +32,6 @@ void SYS_NetBSD_Initialise(void);
void SYS_NetBSD_Finalise(void); void SYS_NetBSD_Finalise(void);
void SYS_NetBSD_DropRoot(uid_t uid, gid_t gid);
#endif #endif