fb633ea
From ee3d4021aaaeacff7cf2addcdaa48859fffba2aa Mon Sep 17 00:00:00 2001
fb633ea
From: Andreas Schwab <schwab@redhat.com>
fb633ea
Date: Thu, 3 Feb 2011 15:45:02 +0100
fb633ea
Subject: [PATCH] Replace setuid by file capabilities
fb633ea
fb633ea
* login/programs/pt_chown.c (main): Check for valid file
fb633ea
descriptor instead of privileges.  Be careful to drop all
fb633ea
capabilities when not needed.
fb633ea
fb633ea
---
fb633ea
 ChangeLog                 |    6 ++++++
fb633ea
 login/programs/pt_chown.c |   14 +++++++++-----
fb633ea
 3 files changed, 16 insertions(+), 6 deletions(-)
fb633ea
fb633ea
--- a/login/programs/pt_chown.c
fb633ea
+++ b/login/programs/pt_chown.c
fb633ea
@@ -28,6 +28,7 @@
fb633ea
 #include <string.h>
fb633ea
 #include <sys/stat.h>
fb633ea
 #include <unistd.h>
fb633ea
+#include <fcntl.h>
fb633ea
 #ifdef HAVE_LIBCAP
fb633ea
 # include <sys/capability.h>
fb633ea
 # include <sys/prctl.h>
fb633ea
@@ -142,7 +143,7 @@ main (int argc, char *argv[])
fb633ea
   uid_t uid = getuid ();
fb633ea
   int remaining;
fb633ea
 
fb633ea
-  if (argc == 1 && euid == 0)
fb633ea
+  if (argc == 1 && fcntl (PTY_FILENO, F_GETFD) == 0)
fb633ea
     {
fb633ea
 #ifdef HAVE_LIBCAP
fb633ea
   /* Drop privileges.  */
fb633ea
@@ -175,6 +176,13 @@ main (int argc, char *argv[])
fb633ea
 
fb633ea
   /* We aren't going to be using privileges, so drop them right now. */
fb633ea
   setuid (uid);
fb633ea
+#ifdef HAVE_LIBCAP
fb633ea
+  cap_t caps = cap_init ();
fb633ea
+  if (caps == NULL)
fb633ea
+    error (1, errno, "cap_init");
fb633ea
+  cap_set_proc (caps);
fb633ea
+  cap_free (caps);
fb633ea
+#endif
fb633ea
 
fb633ea
   /* Set locale via LC_ALL.  */
fb633ea
   setlocale (LC_ALL, "");
fb633ea
@@ -194,9 +202,5 @@ main (int argc, char *argv[])
fb633ea
       return EXIT_FAILURE;
fb633ea
     }
fb633ea
 
fb633ea
-  /* Check if we are properly installed.  */
fb633ea
-  if (euid != 0)
fb633ea
-    error (FAIL_EXEC, 0, gettext ("needs to be installed setuid `root'"));
fb633ea
-
fb633ea
   return EXIT_SUCCESS;
fb633ea
 }