From 0439361f817c3f610c1f5ec859bd302867472e50 Mon Sep 17 00:00:00 2001
From: Jeremie Koenig <jk@jk.fr.eu.org>
Date: Mon, 23 Aug 2010 11:02:13 +0000
Subject: Fix the handling of processes without an owner

* main.c (argp_parser): New option --anonymous-owner.
* main.h: Publish it.
* process.c (process_lookup_pid): Use it to set the file owner
  uid of non-owned processes.
---
 main.c    | 22 ++++++++++++++++++++++
 main.h    |  1 +
 process.c |  4 +++-
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/main.c b/main.c
index 91156485..06c1da04 100644
--- a/main.c
+++ b/main.c
@@ -16,10 +16,12 @@ int opt_clk_tck;
 mode_t opt_stat_mode;
 pid_t opt_fake_self;
 pid_t opt_kernel_pid;
+uid_t opt_anon_owner;
 
 static error_t
 argp_parser (int key, char *arg, struct argp_state *state)
 {
+  struct passwd *pw;
   char *endp;
 
   switch (key)
@@ -58,6 +60,20 @@ argp_parser (int key, char *arg, struct argp_state *state)
       opt_stat_mode = 0444;
       opt_fake_self = 1;
       break;
+
+    case 'a':
+      pw = getpwnam (arg);
+      if (pw)
+	{
+	  opt_anon_owner = pw->pw_uid;
+	  break;
+	}
+
+      opt_anon_owner = strtol (arg, &endp, 0);
+      if (*endp || ! *arg || (signed) opt_anon_owner < 0)
+	error(1, 0, "--anonymous-owner: USER should be the a user name "
+		    "or a numeric UID.");
+      break;
   }
 
   return 0;
@@ -84,6 +100,11 @@ struct argp argp = {
     { "compatible", 'c', NULL, 0,
 	"Try to be compatible with the Linux procps utilities.  "
 	"Currently equivalent to -h 100 -s 0444 -S 1." },
+    { "anonymous-owner", 'a', "USER", 0,
+	"Make USER the owner of files related to processes without one.  "
+	"Be aware that USER will be granted access to the environment and "
+	"other sensitive information about the processes in question.  "
+	"(default: use uid 0)" },
     {}
   },
   .parser = argp_parser,
@@ -138,6 +159,7 @@ int main (int argc, char **argv)
   opt_stat_mode = 0400;
   opt_fake_self = -1;
   opt_kernel_pid = 2;
+  opt_anon_owner = 0;
   err = argp_parse (&argp, argc, argv, 0, 0, 0);
   if (err)
     error (1, err, "Could not parse command line");
diff --git a/main.h b/main.h
index 6ada229a..28d1b023 100644
--- a/main.h
+++ b/main.h
@@ -3,3 +3,4 @@ extern int opt_clk_tck;
 extern mode_t opt_stat_mode;
 extern pid_t opt_fake_self;
 extern pid_t opt_kernel_pid;
+extern uid_t opt_anon_owner;
diff --git a/process.c b/process.c
index b2b098ff..7f5646ae 100644
--- a/process.c
+++ b/process.c
@@ -314,6 +314,7 @@ error_t
 process_lookup_pid (struct ps_context *pc, pid_t pid, struct node **np)
 {
   struct proc_stat *ps;
+  int owner;
   error_t err;
 
   err = _proc_stat_create (pid, pc, &ps);
@@ -334,6 +335,7 @@ process_lookup_pid (struct ps_context *pc, pid_t pid, struct node **np)
   if (! *np)
     return ENOMEM;
 
-  procfs_node_chown (*np, proc_stat_owner_uid (ps));
+  owner = proc_stat_owner_uid (ps);
+  procfs_node_chown (*np, owner >= 0 ? owner : opt_anon_owner);
   return 0;
 }
-- 
cgit v1.2.3