diff --git a/chrony.texi.in b/chrony.texi.in index 18ebfce..895b9d5 100644 --- a/chrony.texi.in +++ b/chrony.texi.in @@ -978,7 +978,13 @@ This option sets the name of the system user to which @code{chronyd} will switch after start in order to drop root privileges. It overrides the @code{user} directive (default @code{@DEFAULT_USER@}). It may be set to a non-root user only when @code{chronyd} is compiled with support for Linux -capabilities (libcap) or on NetBSD with the @code{/dev/clockctl} device. +capabilities (libcap), on NetBSD with the @code{/dev/clockctl} device or on +Mac OS X. + +In the Mac OS X implementation @code{chronyd} forks into two processes. The +child process retains root privileges but can only perform a very limited range +of privileged system calls on behalf of the parent. The parent process drops +root privileges to run as the specified system user. @item -F This option configures a system call filter when @code{chronyd} is compiled with support for the Linux secure computing (seccomp) facility. In level 1 the @@ -3169,8 +3175,13 @@ Valid measurements with corresponding compensations are logged to the The @code{user} directive sets the name of the system user to which @code{chronyd} will switch after start in order to drop root privileges. It may be set to a non-root user only when @code{chronyd} is compiled with -support for Linux capabilities (libcap) or on NetBSD with the -@code{/dev/clockctl} device. +support for Linux capabilities (libcap), on NetBSD with the +@code{/dev/clockctl} device or on Mac OS X. + +In the Mac OS X implementation @code{chronyd} forks into two processes. The +child process retains root privileges but can only perform a very limited range +of privileged system calls on behalf of the parent. The parent process drops +root privileges to run as the specified system user. The default value is @code{@DEFAULT_USER@}. @c }}} diff --git a/chronyd.8.in b/chronyd.8.in index b5b0882..0a10d01 100644 --- a/chronyd.8.in +++ b/chronyd.8.in @@ -103,7 +103,12 @@ This option sets the name of the system user to which \fBchronyd\fR will switch after start in order to drop root privileges. It overrides the \fBuser\fR directive (default \fB@DEFAULT_USER@\fR). It may be set to a non-root user only when \fBchronyd\fR is compiled with support for Linux capabilities -(libcap) or on NetBSD with the \fB/dev/clockctl\fR device. +(libcap), on NetBSD with the \fB/dev/clockctl\fR device or on Mac OS X. + +In the Mac OS X implementation \fBchronyd\fR forks into two processes. The +child process retains root privileges but can only perform a very limited range +of privileged system calls on behalf of the parent. The parent process drops +root privileges to run as the specified system user. .TP \fB\-F\fR \fIlevel\fR This option configures a system call filter when \fBchronyd\fR is compiled with diff --git a/configure b/configure index 16fdf8d..5a52abf 100755 --- a/configure +++ b/configure @@ -392,6 +392,14 @@ case $OPERATINGSYSTEM in EXTRA_LIBS="-lresolv" EXTRA_CLI_LIBS="-lresolv" add_def MACOSX + if [ $feat_droproot = "1" ]; then + EXTRA_OBJECTS="$EXTRA_OBJECTS privops.o" + add_def PRIVOPS_ADJUSTTIME + add_def PRIVOPS_SETTIME + add_def PRIVOPS_BINDSOCKET + add_def PRIVOPS_HELPER + add_def FEAT_PRIVDROP + fi echo "Configuring for MacOS X (" $SYSTEM "MacOS X version" $VERSION ")" ;; SunOS) diff --git a/ntp_io.c b/ntp_io.c index 24b1190..4c250ae 100644 --- a/ntp_io.c +++ b/ntp_io.c @@ -37,6 +37,7 @@ #include "local.h" #include "logging.h" #include "conf.h" +#include "privops.h" #include "util.h" #define INVALID_SOCK_FD -1 @@ -221,7 +222,7 @@ prepare_socket(int family, int port_number, int client_only) #endif /* Bind the socket if a port or address was specified */ - if (my_addr_len > 0 && bind(sock_fd, &my_addr.u, my_addr_len) < 0) { + if (my_addr_len > 0 && PRV_BindSocket(sock_fd, &my_addr.u, my_addr_len) < 0) { LOG(LOGS_ERR, LOGF_NtpIO, "Could not bind %s NTP socket : %s", UTI_SockaddrFamilyToString(family), strerror(errno)); close(sock_fd); diff --git a/sys.c b/sys.c index 4009796..f3844c6 100644 --- a/sys.c +++ b/sys.c @@ -92,6 +92,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid) SYS_Linux_DropRoot(uid, gid); #elif defined(NETBSD) && defined(FEAT_PRIVDROP) SYS_NetBSD_DropRoot(uid, gid); +#elif defined(MACOSX) && defined(FEAT_PRIVDROP) + SYS_MacOSX_DropRoot(uid, gid); #else LOG_FATAL(LOGF_Sys, "dropping root privileges not supported"); #endif diff --git a/sys_macosx.c b/sys_macosx.c index d1b620f..bda7308 100644 --- a/sys_macosx.c +++ b/sys_macosx.c @@ -50,6 +50,7 @@ #include "localp.h" #include "sched.h" #include "logging.h" +#include "privops.h" #include "util.h" /* ================================================== */ @@ -117,7 +118,7 @@ clock_initialise(void) newadj.tv_sec = 0; newadj.tv_usec = 0; - if (adjtime(&newadj, &oldadj) < 0) { + if (PRV_AdjustTime(&newadj, &oldadj) < 0) { LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed"); } } @@ -169,7 +170,7 @@ start_adjust(void) UTI_TimevalToDouble(&newadj, &adjustment_requested); rounding_error = adjust_required - adjustment_requested; - if (adjtime(&newadj, &oldadj) < 0) { + if (PRV_AdjustTime(&newadj, &oldadj) < 0) { LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed"); } @@ -193,7 +194,7 @@ stop_adjust(void) zeroadj.tv_sec = 0; zeroadj.tv_usec = 0; - if (adjtime(&zeroadj, &remadj) < 0) { + if (PRV_AdjustTime(&zeroadj, &remadj) < 0) { LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed"); } @@ -244,7 +245,7 @@ apply_step_offset(double offset) UTI_AddDoubleToTimeval(&old_time, -offset, &new_time); - if (settimeofday(&new_time, NULL) < 0) { + if (PRV_SetTime(&new_time, NULL) < 0) { DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed"); return 0; } @@ -400,6 +401,26 @@ SYS_MacOSX_SetScheduler(int SchedPriority) /* ================================================== */ +#ifdef FEAT_PRIVDROP +void SYS_MacOSX_DropRoot(uid_t uid, gid_t gid) +{ + PRV_Initialise(); + + if (setgroups(0, NULL)) + LOG_FATAL(LOGF_SysMacOSX, "setgroups() failed : %s", strerror(errno)); + + if (setgid(gid)) + LOG_FATAL(LOGF_SysMacOSX, "setgid(%d) failed : %s", gid, strerror(errno)); + + if (setuid(uid)) + LOG_FATAL(LOGF_SysMacOSX, "setuid(%d) failed : %s", uid, strerror(errno)); + + DEBUG_LOG(LOGF_SysMacOSX, "Root dropped to uid %d gid %d", uid, gid); +} +#endif + +/* ================================================== */ + void SYS_MacOSX_Initialise(void) { @@ -423,6 +444,9 @@ SYS_MacOSX_Finalise(void) SCH_RemoveTimeout(drift_removal_id); clock_finalise(); +#ifdef FEAT_PRIVDROP + PRV_Finalise(); +#endif } /* ================================================== */ diff --git a/sys_macosx.h b/sys_macosx.h index 707700d..b9114ff 100644 --- a/sys_macosx.h +++ b/sys_macosx.h @@ -31,6 +31,7 @@ #define GOT_SYS_MACOSX_H void SYS_MacOSX_SetScheduler(int SchedPriority); +void SYS_MacOSX_DropRoot(uid_t uid, gid_t gid); void SYS_MacOSX_Initialise(void); void SYS_MacOSX_Finalise(void);