[chrony-dev] [PATCH] MacOS X - Drop root privileges |
[ Thread Index |
Date Index
| More chrony.tuxfamily.org/chrony-dev Archives
]
- To: chrony-dev@xxxxxxxxxxxxxxxxxxxx
- Subject: [chrony-dev] [PATCH] MacOS X - Drop root privileges
- From: Bryan Christianson <bryan@xxxxxxxxxxxxx>
- Date: Sat, 12 Sep 2015 22:30:05 +1200
- Cc: Bryan Christianson <bryan@xxxxxxxxxxxxx>
- Dkim-signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpcorp.com; s=a0-2; h=Feedback-ID:X-Smtpcorp-Track:Message-Id:Date: Subject:To:From; bh=l8uy7jEpOQLwGqxDUmCmYH19m6CzoAPZSZ+n5I3iqPc=; b=XCiLBNUoo y0opfiv/NNAI2tqyWjenyOmJS1Fb8BjNqAsqqK7Ajy0WlTLwjhPIg48jsRA59yFY2wWF/QR6CkA71 zUnQwsEPQxbzMAXRkbCrox4pM6PmWgvuW80yI3FbNumhGAwgNKMsBM2e4xObUQo8S1TvxK/aIRqVP kgGGjRxxJdNKHHFkMYLTnZXb8HqMcubQEJsCJkC2sfusxHDGigPVFzW1y7K/SddCgC4BWwdVDDd69 KAnOTdP16mEaxlQ7iqlpPkvxGB8Bpg1KLP+6Q0dQOpnB3fvE4I3wYDtHchUu4SsbXCJCtqf39g4Nj qBJhw/PswTty+SezfCGFtISFg==;
- Feedback-id: 149811m:149811acx33YQ:149811s7H6Txr-X0:SMTPCORP
When a user is specified to chronyd (command line or config file), chronyd
will drop privileges, restoring them when required for privileged system
calls.
---
chrony.texi.in | 7 +++--
configure | 3 ++
sys.c | 2 ++
sys_macosx.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
sys_macosx.h | 2 ++
5 files changed, 96 insertions(+), 7 deletions(-)
diff --git a/chrony.texi.in b/chrony.texi.in
index e26e61c..37dd526 100644
--- a/chrony.texi.in
+++ b/chrony.texi.in
@@ -999,7 +999,8 @@ 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 MacOS X.
@item -F <level>
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
@@ -3179,8 +3180,8 @@ 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 and on MacOS X.
The default value is @code{@DEFAULT_USER@}.
@c }}}
diff --git a/configure b/configure
index abdbf2d..cec6334 100755
--- a/configure
+++ b/configure
@@ -430,6 +430,9 @@ case $SYSTEM in
EXTRA_LIBS="-lresolv"
EXTRA_CLI_LIBS="-lresolv"
add_def MACOSX
+ if [ $feat_droproot = "1" ]; then
+ add_def FEAT_PRIVDROP
+ fi
echo "Configuring for MacOS X (" $SYSTEM "MacOS X version" $VERSION ")"
;;
SunOS-i86pc* )
diff --git a/sys.c b/sys.c
index c5c4250..1dd4ed7 100644
--- a/sys.c
+++ b/sys.c
@@ -113,6 +113,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid)
{
#if defined(LINUX) && defined (FEAT_PRIVDROP)
SYS_Linux_DropRoot(uid, gid);
+#elif defined(MACOSX) && defined(FEAT_PRIVDROP)
+ SYS_MacOSX_DropRoot(uid, gid);
#elif defined(NETBSD) && defined(FEAT_PRIVDROP)
SYS_NetBSD_DropRoot(uid, gid);
#else
diff --git a/sys_macosx.c b/sys_macosx.c
index 200b62c..77691c5 100644
--- a/sys_macosx.c
+++ b/sys_macosx.c
@@ -96,6 +96,77 @@ static struct timeval Tdrift;
#define NANOS_PER_MSEC (1000000ULL)
+/* Effective UID and GID - when privileges are dropped */
+
+static uid_t s_euid = 0;
+static gid_t s_egid = 0;
+
+/* ================================================== */
+
+/* drop root privileges */
+
+static inline void
+priv_disable(void)
+{
+ if (s_egid != 0 && setegid(s_egid) != 0) {
+ LOG_FATAL(LOGF_SysMacOSX, "setegid(%d) failed: %s", s_egid, strerror(errno));
+ }
+
+ if (s_euid != 0 && seteuid(s_euid) != 0) {
+ LOG_FATAL(LOGF_SysMacOSX, "seteuid(%d) failed: %s", s_euid, strerror(errno));
+ }
+}
+
+/* ================================================== */
+
+/* restore root privileges */
+
+static inline void
+priv_enable(void)
+{
+ if (s_euid == 0 && s_egid == 0) {
+ return;
+ }
+
+ if (seteuid(0) != 0) {
+ LOG_FATAL(LOGF_SysMacOSX, "seteuid(%d) failed: %s", 0, strerror(errno));
+ }
+
+ if (setegid(0) != 0) {
+ LOG_FATAL(LOGF_SysMacOSX, "setegid(%d) failed: %s", 0, strerror(errno));
+ }
+}
+
+/* ================================================== */
+
+/* adjtime() wrapper - regain root privileges and drop on completion */
+
+static inline int
+mac_adjtime(const struct timeval *delta, struct timeval *olddelta)
+{
+ int ret;
+
+ priv_enable();
+ ret = adjtime(delta, olddelta);
+ priv_disable();
+ return ret;
+}
+
+/* ================================================== */
+
+/* settimeofday() wrapper - regain root privileges and drop on completion */
+
+static inline int
+mac_settimeofday(const struct timeval *tp, const struct timezone *tzp)
+{
+ int ret;
+
+ priv_enable();
+ ret = settimeofday(tp, tzp);
+ priv_disable();
+ return ret;
+}
+
/* ================================================== */
static void
@@ -117,7 +188,7 @@ clock_initialise(void)
newadj.tv_sec = 0;
newadj.tv_usec = 0;
- if (adjtime(&newadj, &oldadj) < 0) {
+ if (mac_adjtime(&newadj, &oldadj) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
}
@@ -169,7 +240,7 @@ start_adjust(void)
UTI_TimevalToDouble(&newadj, &adjustment_requested);
rounding_error = adjust_required - adjustment_requested;
- if (adjtime(&newadj, &oldadj) < 0) {
+ if (mac_adjtime(&newadj, &oldadj) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
@@ -193,7 +264,7 @@ stop_adjust(void)
zeroadj.tv_sec = 0;
zeroadj.tv_usec = 0;
- if (adjtime(&zeroadj, &remadj) < 0) {
+ if (mac_adjtime(&zeroadj, &remadj) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
@@ -244,7 +315,7 @@ apply_step_offset(double offset)
UTI_AddDoubleToTimeval(&old_time, -offset, &new_time);
- if (settimeofday(&new_time, NULL) < 0) {
+ if (mac_settimeofday(&new_time, NULL) < 0) {
DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed");
return 0;
}
@@ -431,4 +502,14 @@ SYS_MacOSX_Finalise(void)
/* ================================================== */
+void SYS_MacOSX_DropRoot(uid_t uid, gid_t gid)
+{
+ s_euid = uid;
+ s_egid = gid;
+
+ priv_disable();
+}
+
+/* ================================================== */
+
#endif
diff --git a/sys_macosx.h b/sys_macosx.h
index 707700d..fbe3527 100644
--- a/sys_macosx.h
+++ b/sys_macosx.h
@@ -34,4 +34,6 @@ void SYS_MacOSX_SetScheduler(int SchedPriority);
void SYS_MacOSX_Initialise(void);
void SYS_MacOSX_Finalise(void);
+void SYS_MacOSX_DropRoot(uid_t uid, gid_t gid);
+
#endif
--
2.3.2 (Apple Git-55)
--
To unsubscribe email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "unsubscribe" in the subject.
For help email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "help" in the subject.
Trouble? Email listmaster@xxxxxxxxxxxxxxxxxxxx.