Sophie

Sophie

distrib > Mandriva > 2008.0 > x86_64 > by-pkgid > 3cdb4c56b81d281321b426ee93b198c9 > files > 20

ntp-4.2.4-12mdv2008.0.src.rpm

--- 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);