--- ntpd/ntpd.c 2007-09-25 13:23:13.000000000 +0200 +++ ntpd/ntpd.c.oden 2007-09-25 13:23:36.000000000 +0200 @@ -168,6 +168,8 @@ int droproot = 0; char *user = NULL; /* User to switch to */ char *group = NULL; /* group to switch to */ char *chrootdir = NULL; /* directory to chroot to */ +int have_caps = 0; /* runtime check whether capabilities work, + leave at 0 here */ int sw_uid; int sw_gid; char *endp; @@ -851,8 +853,29 @@ ntpdmain( #endif /* OPENSSL */ initializing = 0; +#ifdef HAVE_LINUX_CAPABILITIES + { + /* Check that setting capabilities actually works; we might be + * run on a kernel with disabled capabilities. We must not + * drop privileges in this case. + */ + cap_t caps; + if( ! ( caps = cap_from_text( "cap_sys_time,cap_setuid,cap_setgid,cap_sys_chroot,cap_net_bind_service=pe" ) ) ) { + msyslog( LOG_ERR, "cap_from_text() failed: %m" ); + exit(-1); + } + if( cap_set_proc( caps ) == 0 ) + have_caps = 1; + cap_free( caps ); + } +#endif /* HAVE_LINUX_CAPABILITIES */ + #ifdef HAVE_DROPROOT +#ifdef HAVE_LINUX_CAPABILITIES + if( droproot && have_caps ) { +#else if( droproot ) { +#endif /* Drop super-user privileges and chroot now if the OS supports this */ #ifdef HAVE_LINUX_CAPABILITIES @@ -887,7 +910,6 @@ getuser: sw_uid = pw->pw_uid; sw_gid = pw->pw_gid; } else { - errno = 0; msyslog(LOG_ERR, "Cannot find user `%s'", user); exit (-1); } @@ -968,8 +990,8 @@ getgroup: */ cap_t caps; char *captext = interface_interval ? - "cap_sys_time,cap_net_bind_service=ipe" : - "cap_sys_time=ipe"; + "cap_sys_time,cap_net_bind_service=pe" : + "cap_sys_time=pe"; if( ! ( caps = cap_from_text( captext ) ) ) { msyslog( LOG_ERR, "cap_from_text() failed: %m" ); exit(-1);