]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
boot-server: print who is making requests
authorRay Strode <rstrode@redhat.com>
Wed, 8 Sep 2010 14:31:31 +0000 (10:31 -0400)
committerRay Strode <rstrode@redhat.com>
Wed, 8 Sep 2010 15:39:38 +0000 (11:39 -0400)
One of the big painpoints in plymouth distro integration
out which distro scripts are calling into plymouthd.

This commit makes plymouthd output that information whenever
there is a request from a connected client.

src/libply/ply-utils.c
src/libply/ply-utils.h
src/ply-boot-server.c

index 0d7bdd669808aecca82aebf3e7212292f70a8f4b..d80107018534753aeac516170d264c6a750ffa1b 100644 (file)
@@ -40,6 +40,7 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/un.h>
+#include <sys/user.h>
 #include <time.h>
 #include <linux/fs.h>
 #include <linux/vt.h>
@@ -939,4 +940,93 @@ ply_utf8_string_get_length (const char   *string,
   return count;
 }
 
+char *
+ply_get_process_command_line (pid_t pid)
+{
+  char *path;
+  char *command_line;
+  ssize_t bytes_read;
+  int fd;
+  ssize_t i;
+
+  path = NULL;
+  command_line = NULL;
+
+  asprintf (&path, "/proc/%ld/cmdline", (long) pid);
+
+  fd = open (path, O_RDONLY);
+
+  if (fd < 0)
+    {
+      ply_trace ("Could not open %s: %m", path);
+      goto error;
+    }
+
+  command_line = calloc (PAGE_SIZE, sizeof (char));
+  bytes_read = read (fd, command_line, PAGE_SIZE - 1);
+  if (bytes_read < 0)
+    {
+      ply_trace ("Could not read %s: %m", path);
+      close (fd);
+      goto error;
+    }
+  close (fd);
+  free (path);
+
+  for (i = 0; i < bytes_read - 1; i++)
+    {
+      if (command_line[i] == '\0')
+        command_line[i] = ' ';
+    }
+  command_line[i] = '\0';
+
+  return command_line;
+
+error:
+  free (path);
+  free (command_line);
+  return NULL;
+}
+
+pid_t
+ply_get_process_parent_pid (pid_t pid)
+{
+  char *path;
+  char *stat;
+  FILE *fp;
+  int ppid;
+
+  asprintf (&path, "/proc/%ld/stat", (long) pid);
+
+  ppid = 0;
+  fp = fopen (path, "r");
+
+  if (fp == NULL)
+    {
+      ply_trace ("Could not open %s: %m", path);
+      goto out;
+    }
+
+  stat = calloc (PAGE_SIZE, sizeof (char));
+  if (fscanf (fp, "%*d %*s %*c %d", &ppid) != 1)
+    {
+      ply_trace ("Could not parse %s: %m", path);
+      goto out;
+    }
+
+  if (ppid <= 0)
+    {
+      ply_trace ("%s is returning invalid parent pid %d", path, ppid);
+      ppid = 0;
+      goto out;
+    }
+
+out:
+  free (path);
+
+  if (fp != NULL)
+    fclose (fp);
+
+  return (pid_t) ppid;
+}
 /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
index 2c4b3c73fa537aba32e650ba5697fc09ef1290f6..8af8172d8221b2c06ba0cd2ac8196c480b57655c 100644 (file)
@@ -110,6 +110,9 @@ int ply_utf8_character_get_size (const char   *string,
 int ply_utf8_string_get_length (const char   *string,
                                 size_t        n);
 
+char *ply_get_process_command_line (pid_t pid);
+pid_t ply_get_process_parent_pid (pid_t pid);
+
 #endif
 
 #endif /* PLY_UTILS_H */
index d744a204df2b7c6d845f8754a812f56f33dc8d79..297074ec0135fd8f8ac1c88e4166f08c020d30a7 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
 
 #include "ply-trigger.h"
 #include "ply-utils.h"
 
-typedef struct 
+typedef struct
 {
   int fd;
   ply_fd_watch_t *watch;
   ply_boot_server_t *server;
+  uid_t uid;
+  pid_t pid;
+
+  uint32_t credentials_read : 1;
 } ply_boot_connection_t;
 
 struct _ply_boot_server
@@ -198,6 +203,8 @@ ply_boot_connection_read_request (ply_boot_connection_t  *connection,
   assert (connection != NULL);
   assert (connection->fd >= 0);
 
+  connection->credentials_read = false;
+
   if (!ply_read (connection->fd, header, sizeof (header)))
     return false;
 
@@ -224,21 +231,31 @@ ply_boot_connection_read_request (ply_boot_connection_t  *connection,
           return false;
         }
     }
+
+  if (!ply_get_credentials_from_fd (connection->fd, &connection->pid, &connection->uid, NULL))
+    {
+      ply_trace ("couldn't read credentials from connection: %m");
+      free (*argument);
+      free (*command);
+      return false;
+    }
+  connection->credentials_read = true;
+
   return true;
 }
 
 static bool
 ply_boot_connection_is_from_root (ply_boot_connection_t *connection)
 {
-  uid_t uid;
-
-  if (!ply_get_credentials_from_fd (connection->fd, NULL, &uid, NULL))
-    return false;
+  if (!connection->credentials_read)
+    {
+      ply_trace ("Asked if connection is from root, but haven't checked credentials yet");
+      return false;
+    }
 
-  return uid == 0;
+  return connection->uid == 0;
 }
 
-
 static void
 ply_boot_connection_send_answer (ply_boot_connection_t *connection,
                                  const char            *answer)
@@ -325,6 +342,24 @@ ply_boot_connection_on_keystroke_answer (ply_boot_connection_t *connection,
   ply_boot_connection_send_answer (connection, key);
 }
 
+static void
+print_connection_process_identity (ply_boot_connection_t *connection)
+{
+  char *command_line, *parent_command_line;
+  pid_t parent_pid;
+
+  command_line = ply_get_process_command_line (connection->pid);
+  parent_pid = ply_get_process_parent_pid (connection->pid);
+  parent_command_line = ply_get_process_command_line (parent_pid);
+
+  ply_trace ("connection is from pid %ld (%s) with parent pid %ld (%s)",
+             (long) connection->pid, command_line,
+             (long) parent_pid, parent_command_line);
+
+  free (command_line);
+  free (parent_command_line);
+}
+
 static void
 ply_boot_connection_on_request (ply_boot_connection_t *connection)
 {
@@ -344,6 +379,9 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
       return;
     }
 
+  if (ply_is_tracing ())
+    print_connection_process_identity (connection);
+
   if (!ply_boot_connection_is_from_root (connection))
     {
       ply_error ("request came from non-root user");