Linux capabilities support
Attached is a patch adding a linux capabilities support to chronyd. It adds -u option which can be used to specify the user which chronyd should switch to.
This commit is contained in:
parent
8336f14680
commit
be42b4eeea
8 changed files with 95 additions and 6 deletions
|
@ -1089,6 +1089,9 @@ to work well, it relies on @code{chronyd} having been able to determine
|
|||
accurate statistics for the difference between the real time clock and
|
||||
system clock last time the computer was on.
|
||||
|
||||
@item -u <user>
|
||||
When this option is used, chronyd will drop root privileges to the specified
|
||||
user. So far, it works only on Linux when compiled with capabilities support.
|
||||
@item -v
|
||||
This option displays @code{chronyd's} version number to the terminal and
|
||||
exits.
|
||||
|
|
|
@ -79,6 +79,10 @@ been able to determine accurate statistics for the difference
|
|||
between the real time clock and system clock last time the
|
||||
computer was on.
|
||||
.TP
|
||||
\fB\-u\fR \fIuser\fR
|
||||
When this option is used, chronyd will drop root privileges to the specified
|
||||
user. So far, it works only on Linux when compiled with capabilities support.
|
||||
.TP
|
||||
.B \-v
|
||||
This option displays \fBchronyd\fR's version number to the terminal and exits
|
||||
|
||||
|
|
9
configure
vendored
9
configure
vendored
|
@ -134,6 +134,7 @@ For better control, use the options below.
|
|||
--readline-lib-dir=DIR Specify where readline lib directory is
|
||||
--with-ncurses-library=DIR Specify where ncurses lib directory is
|
||||
--disable-rtc Don't include RTC even on Linux
|
||||
--enable-linuxcaps Enable Linux capabilities support
|
||||
|
||||
Fine tuning of the installation directories:
|
||||
--infodir=DIR info documentation [PREFIX/info]
|
||||
|
@ -174,6 +175,7 @@ SYSDEFS=""
|
|||
# Support for readline (on by default)
|
||||
feat_readline=1
|
||||
feat_rtc=1
|
||||
feat_linuxcaps=0
|
||||
readline_lib=""
|
||||
readline_inc=""
|
||||
ncurses_lib=""
|
||||
|
@ -211,6 +213,9 @@ do
|
|||
--disable-rtc)
|
||||
feat_rtc=0
|
||||
;;
|
||||
--enable-linuxcaps)
|
||||
feat_linuxcaps=1
|
||||
;;
|
||||
--help | -h )
|
||||
usage
|
||||
exit 0
|
||||
|
@ -248,6 +253,10 @@ case $SYSTEM in
|
|||
EXTRA_OBJECTS+=" rtc_linux.o"
|
||||
EXTRA_DEFS+=" -DFEAT_RTC=1"
|
||||
fi
|
||||
if [ $feat_linuxcaps -eq 1 ] ; then
|
||||
EXTRA_DEFS+=" -DFEAT_LINUXCAPS=1"
|
||||
EXTRA_LIBS="-lcap"
|
||||
fi
|
||||
SYSDEFS="-DLINUX"
|
||||
echo "Configuring for " $SYSTEM
|
||||
if [ "${MACHINE}" = "alpha" ]; then
|
||||
|
|
20
main.c
20
main.c
|
@ -83,19 +83,19 @@ MAI_CleanupAndExit(void)
|
|||
SRC_DumpSources();
|
||||
}
|
||||
|
||||
RTC_Finalise();
|
||||
MNL_Finalise();
|
||||
ACQ_Finalise();
|
||||
CAM_Finalise();
|
||||
KEY_Finalise();
|
||||
CLG_Finalise();
|
||||
NIO_Finalise();
|
||||
NSR_Finalise();
|
||||
NCR_Finalise();
|
||||
BRD_Finalise();
|
||||
SRC_Finalise();
|
||||
SST_Finalise();
|
||||
REF_Finalise();
|
||||
RTC_Finalise();
|
||||
CAM_Finalise();
|
||||
NIO_Finalise();
|
||||
SYS_Finalise();
|
||||
SCH_Finalise();
|
||||
LCL_Finalise();
|
||||
|
@ -206,6 +206,7 @@ int main
|
|||
(int argc, char **argv)
|
||||
{
|
||||
char *conf_file = NULL;
|
||||
char *user = NULL;
|
||||
int debug = 0;
|
||||
int do_init_rtc = 0;
|
||||
int other_pid;
|
||||
|
@ -220,6 +221,9 @@ int main
|
|||
conf_file = *argv;
|
||||
} else if (!strcmp("-r", *argv)) {
|
||||
reload = 1;
|
||||
} else if (!strcmp("-u", *argv)) {
|
||||
++argv, --argc;
|
||||
user = *argv;
|
||||
} else if (!strcmp("-s", *argv)) {
|
||||
do_init_rtc = 1;
|
||||
} else if (!strcmp("-v", *argv) || !strcmp("--version",*argv)) {
|
||||
|
@ -269,19 +273,23 @@ int main
|
|||
LCL_Initialise();
|
||||
SCH_Initialise();
|
||||
SYS_Initialise();
|
||||
NIO_Initialise();
|
||||
CAM_Initialise();
|
||||
RTC_Initialise();
|
||||
|
||||
if (user)
|
||||
SYS_DropRoot(user);
|
||||
|
||||
REF_Initialise();
|
||||
SST_Initialise();
|
||||
SRC_Initialise();
|
||||
BRD_Initialise();
|
||||
NCR_Initialise();
|
||||
NSR_Initialise();
|
||||
NIO_Initialise();
|
||||
CLG_Initialise();
|
||||
KEY_Initialise();
|
||||
CAM_Initialise();
|
||||
ACQ_Initialise();
|
||||
MNL_Initialise();
|
||||
RTC_Initialise();
|
||||
|
||||
/* From now on, it is safe to do finalisation on exit */
|
||||
initialised = 1;
|
||||
|
|
8
sys.c
8
sys.c
|
@ -97,6 +97,14 @@ SYS_Finalise(void)
|
|||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void SYS_DropRoot(char *user)
|
||||
{
|
||||
#if defined(LINUX) && defined (FEAT_LINUXCAPS)
|
||||
SYS_Linux_DropRoot(user);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* ================================================== */
|
||||
|
||||
|
|
3
sys.h
3
sys.h
|
@ -39,4 +39,7 @@ extern void SYS_Initialise(void);
|
|||
/* Called at the end of the run to do final clean-up */
|
||||
extern void SYS_Finalise(void);
|
||||
|
||||
/* Drop root privileges to the specified user */
|
||||
extern void SYS_DropRoot(char *user);
|
||||
|
||||
#endif /* GOT_SYS_H */
|
||||
|
|
52
sys_linux.c
52
sys_linux.c
|
@ -39,6 +39,14 @@
|
|||
#include <assert.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#ifdef FEAT_LINUXCAPS
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/capability.h>
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#include "localp.h"
|
||||
#include "sys_linux.h"
|
||||
#include "sched.h"
|
||||
|
@ -831,6 +839,50 @@ SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
#ifdef FEAT_LINUXCAPS
|
||||
void
|
||||
SYS_Linux_DropRoot(char *user)
|
||||
{
|
||||
struct passwd *pw;
|
||||
cap_t cap;
|
||||
|
||||
if (user == NULL)
|
||||
return;
|
||||
|
||||
if ((pw = getpwnam(user)) == NULL) {
|
||||
LOG_FATAL(LOGF_SysLinux, "getpwnam(%s) failed", user);
|
||||
}
|
||||
|
||||
if (prctl(PR_SET_KEEPCAPS, 1)) {
|
||||
LOG_FATAL(LOGF_SysLinux, "prcap() failed");
|
||||
}
|
||||
|
||||
if (setgroups(0, NULL)) {
|
||||
LOG_FATAL(LOGF_SysLinux, "setgroups() failed");
|
||||
}
|
||||
|
||||
if (setgid(pw->pw_gid)) {
|
||||
LOG_FATAL(LOGF_SysLinux, "setgid(%d) failed", pw->pw_gid);
|
||||
}
|
||||
|
||||
if (setuid(pw->pw_uid)) {
|
||||
LOG_FATAL(LOGF_SysLinux, "setuid(%d) failed", pw->pw_uid);
|
||||
}
|
||||
|
||||
if ((cap = cap_from_text("cap_sys_time=ep")) == NULL) {
|
||||
LOG_FATAL(LOGF_SysLinux, "cap_from_text() failed");
|
||||
}
|
||||
|
||||
if (cap_set_proc(cap)) {
|
||||
LOG_FATAL(LOGF_SysLinux, "cap_set_proc() failed");
|
||||
}
|
||||
|
||||
LOG(LOGS_INFO, LOGF_SysLinux, "Privileges dropped to user %s", user);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
#endif /* LINUX */
|
||||
|
||||
/* vim:ts=8
|
||||
|
|
|
@ -37,4 +37,6 @@ extern void SYS_Linux_Finalise(void);
|
|||
|
||||
extern void SYS_Linux_GetKernelVersion(int *major, int *minor, int *patchlevel);
|
||||
|
||||
extern void SYS_Linux_DropRoot(char *user);
|
||||
|
||||
#endif /* GOT_SYS_LINUX_H */
|
||||
|
|
Loading…
Reference in a new issue