#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>
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: */
#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
assert (connection != NULL);
assert (connection->fd >= 0);
+ connection->credentials_read = false;
+
if (!ply_read (connection->fd, header, sizeof (header)))
return false;
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)
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)
{
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");