From: Ray Strode Date: Wed, 8 Sep 2010 14:31:31 +0000 (-0400) Subject: boot-server: print who is making requests X-Git-Tag: 0.8.4~120 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ffdfb78be1bcda708fd89faf645b582f88c6f1d5;p=thirdparty%2Fplymouth.git boot-server: print who is making requests 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. --- diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c index 0d7bdd66..d8010701 100644 --- a/src/libply/ply-utils.c +++ b/src/libply/ply-utils.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -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: */ diff --git a/src/libply/ply-utils.h b/src/libply/ply-utils.h index 2c4b3c73..8af8172d 100644 --- a/src/libply/ply-utils.h +++ b/src/libply/ply-utils.h @@ -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 */ diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index d744a204..297074ec 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -38,11 +39,15 @@ #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");