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.
This commit is contained in:
Ray Strode 2010-09-08 10:31:31 -04:00
parent 2c46832e5d
commit ffdfb78be1
3 changed files with 138 additions and 7 deletions

View 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: */

View 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 */

View 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>
@ -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 (!connection->credentials_read)
{
ply_trace ("Asked if connection is from root, but haven't checked credentials yet");
return false;
}
if (!ply_get_credentials_from_fd (connection->fd, NULL, &uid, NULL))
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");