Date: Mon, 07 Nov 2005 22:17:07 +0100 From: Anatoli Klassen <anatoli@aksoft.net> To: freebsd-hackers@freebsd.org Subject: Run ntpd as non-root user Message-ID: <436FC453.1080801@aksoft.net>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------030509020808000204010009 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi All, I have written patches to allow to run ntpd as ordinal user and/or from jail. The idea is to disable build-in kernel security checks by setting some sysctl's and then plug in a MAC module (actually it is the same approach as in mac_portacl to bind to low ports). There are four new sysctl MIBs: kern.usersettime - non-root is allowed to change system time, kern.jailsettime - system time is allowed to be changed from jail, kern.useradjtime - non-root is allowed to adjust system time, kern.jailadjtime - system time is allowed to be adjusted from jail; and a new MAC module mac_settime, where admin can define rules via sysctl MIB: security.mac.settime.rules= "allow uid 2000 nojail; allow gid 123 jail 10" There is also a one-line patch for ntpd itself to disable root-check at startup. I'm waiting for your comments :) Regards, Anatoli --------------030509020808000204010009 Content-Type: text/plain; name="kern_settime.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kern_settime.patch" --- sys/kern/kern_time.c.orig Mon Nov 7 11:56:57 2005 +++ sys/kern/kern_time.c Mon Nov 7 12:14:45 2005 @@ -41,9 +41,11 @@ #include <sys/sysproto.h> #include <sys/resourcevar.h> #include <sys/signalvar.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/mac.h> #include <sys/syscallsubr.h> +#include <sys/sysctl.h> #include <sys/sysent.h> #include <sys/proc.h> #include <sys/time.h> @@ -104,6 +106,12 @@ SYSINIT(posix_timer, SI_SUB_P1003_1B, SI_ORDER_FIRST+4, itimer_start, NULL); +static int cf_usersettime; +static int cf_jailsettime; +SYSCTL_INT(_kern, OID_AUTO, usersettime, CTLFLAG_RW, &cf_usersettime, 0, + "Non-root is allowed to change system time"); +SYSCTL_INT(_kern, OID_AUTO, jailsettime, CTLFLAG_RW, &cf_jailsettime, 0, + "System time is allowed to be changed from jail"); static void no_lease_updatetime(deltat) @@ -265,8 +273,10 @@ if (error) return (error); #endif - if ((error = suser(td)) != 0) - return (error); + if (!cf_jailsettime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_usersettime && (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked */ if (clock_id != CLOCK_REALTIME) return (EINVAL); if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000) @@ -472,9 +482,12 @@ if (error) return (error); #endif - error = suser(td); - if (error) - return (error); + if (!cf_jailsettime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_usersettime && (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked */ + else + error = 0; /* Verify all parameters before changing time. */ if (tv) { if (tv->tv_usec < 0 || tv->tv_usec >= 1000000) --- sys/kern/kern_ntptime.c.orig Mon Nov 7 11:57:07 2005 +++ sys/kern/kern_ntptime.c Mon Nov 7 12:14:45 2005 @@ -38,6 +38,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/proc.h> #include <sys/lock.h> @@ -198,6 +199,13 @@ static void hardupdate(long offset); static void ntp_gettime1(struct ntptimeval *ntvp); +static int cf_useradjtime; +static int cf_jailadjtime; +SYSCTL_INT(_kern, OID_AUTO, useradjtime, CTLFLAG_RW, &cf_useradjtime, 0, + "Non-root is allowed to adjust system time"); +SYSCTL_INT(_kern, OID_AUTO, jailadjtime, CTLFLAG_RW, &cf_jailadjtime, 0, + "System time is allowed to be adjusted from jail"); + static void ntp_gettime1(struct ntptimeval *ntvp) { @@ -330,12 +338,20 @@ * the STA_PLL bit in the status word is cleared, the state and * status words are reset to the initial values at boot. */ - mtx_lock(&Giant); modes = ntv.modes; - if (modes) - error = suser(td); - if (error) - goto done2; + if (modes) { +#ifdef MAC + error = mac_check_system_settime(td->td_ucred); + if (error) + return (error); +#endif + if (!cf_jailadjtime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_useradjtime && + (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked at this point */ + } + mtx_lock(&Giant); s = splclock(); if (modes & MOD_MAXERROR) time_maxerror = ntv.maxerror; @@ -954,8 +970,17 @@ struct timeval atv; int error; - if ((error = suser(td))) +#ifdef MAC + error = mac_check_system_settime(td->td_ucred); + if (error) return (error); +#endif + if (!cf_jailadjtime && jailed(td->td_ucred)) + return (EPERM); + if (!cf_useradjtime && (error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) + return (error); /* jail is already checked */ + else + error = 0; mtx_lock(&Giant); if (olddelta) { --------------030509020808000204010009 Content-Type: text/plain; name="ntp.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ntp.patch" --- contrib/ntp/ntpd/ntpd.c.orig Mon Nov 7 11:57:28 2005 +++ contrib/ntp/ntpd/ntpd.c Mon Nov 7 12:14:45 2005 @@ -394,7 +394,7 @@ } #endif -#if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ +#if 0 && defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ { uid_t uid; --------------030509020808000204010009--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?436FC453.1080801>