Browse Source

seatd: Remove runtime socket path configuration

Configurable socket paths exist mainly to facilitate multiple parallel
seatd instances. However, the only valid use-case for running multiple
instances of seatd is testing during development, which can just as well
be done by changing SEATD_DEFAULTPATH at compile-time for test builds.

Remove the command-line argument in seatd for runtime configuration of
socket path, hardcode the socket path in seatd-launch, and change seatd
unlink/chmod/chown code to not run when started by seatd-launch.

This means that seatd-launch will now fail to start seatd if another
seatd instance is already running. The unlink code still runs when seatd
is started normally to assist in system crash recovery, but this may be
removed later if we deem it unnecessary.
debian/master
Kenny Levinsen 1 year ago
parent
commit
0d6bdf4f01
  1. 3
      man/seatd-launch.1.scd
  2. 5
      man/seatd.1.scd
  3. 11
      seatd-launch/seatd-launch.c
  4. 53
      seatd/seatd.c

3
man/seatd-launch.1.scd

@ -17,9 +17,6 @@ seatd-launch - Start a process with its own seatd instance
*-h*
Show help message and quit.
*-s <path>*
Where to create the seatd socket. Defaults to a unique file path.
*-v*
Show the version number and quit.

5
man/seatd.1.scd

@ -24,9 +24,6 @@ seatd - A seat management daemon
*-g <group>*
Group to own the seatd socket.
*-s <path>*
Where to create the seatd socket. Defaults to `/run/seatd.sock`.
*-l <loglevel>*
Log-level to use. Must be one of debug, info, error or silent. Defaults
to error.
@ -42,6 +39,8 @@ such as displays and input devices in a multi-session, multi-seat environment.
seatd operates over a UNIX domain socket, with *libseat* providing the
client-side of the protocol.
The location of the socket for seatd is set at compile-time.
# SEE ALSO
The libseat library, *<libseat.h>*, *seatd-launch*(1)

11
seatd-launch/seatd-launch.c

@ -46,9 +46,6 @@ int main(int argc, char *argv[]) {
}
char **command = &argv[optind];
char sockpath[32];
snprintf(sockpath, sizeof sockpath, "/tmp/seatd.%d.sock", getpid());
int readiness_pipe[2];
if (pipe(readiness_pipe) == -1) {
perror("Could not create pipe");
@ -67,7 +64,7 @@ int main(int argc, char *argv[]) {
snprintf(pipebuf, sizeof pipebuf, "%d", readiness_pipe[1]);
char *env[1] = {NULL};
char *command[] = {"seatd", "-n", pipebuf, "-s", sockpath, "-l", loglevel, NULL};
char *command[] = {"seatd", "-n", pipebuf, "-l", loglevel, "-z", NULL};
execve(SEATD_INSTALLPATH, command, env);
perror("Could not start seatd");
_exit(1);
@ -117,11 +114,11 @@ int main(int argc, char *argv[]) {
gid_t gid = getgid();
// Restrict access to the socket to just us
if (chown(sockpath, uid, gid) == -1) {
if (chown(SEATD_DEFAULTPATH, uid, gid) == -1) {
perror("Could not chown seatd socket");
goto error_seatd;
}
if (chmod(sockpath, 0700) == -1) {
if (chmod(SEATD_DEFAULTPATH, 0700) == -1) {
perror("Could not chmod socket");
goto error_seatd;
}
@ -141,7 +138,7 @@ int main(int argc, char *argv[]) {
perror("Could not fork target process");
goto error_seatd;
} else if (child == 0) {
setenv("SEATD_SOCK", sockpath, 1);
setenv("SEATD_SOCK", SEATD_DEFAULTPATH, 1);
execvp(command[0], command);
perror("Could not start target");
_exit(1);

53
seatd/seatd.c

@ -40,15 +40,15 @@ static int open_socket(const char *path, int uid, int gid) {
goto error;
}
if (uid != -1 || gid != -1) {
if (chmod(path, 0770) == -1) {
log_errorf("Could not chmod socket: %s", strerror(errno));
goto error;
}
if (chown(path, uid, gid) == -1) {
log_errorf("Could not chown socket to uid %d, gid %d: %s", uid, gid,
strerror(errno));
goto error;
}
if (chmod(path, 0770) == -1) {
log_errorf("Could not chmod socket: %s", strerror(errno));
goto error;
}
}
return fd;
error:
@ -63,7 +63,6 @@ int main(int argc, char *argv[]) {
" -n <fd> FD to notify readiness on\n"
" -u <user> User to own the seatd socket\n"
" -g <group> Group to own the seatd socket\n"
" -s <path> Where to create the seatd socket\n"
" -l <loglevel> Log-level, one of debug, info, error or silent\n"
" -v Show the version number\n"
"\n";
@ -71,9 +70,10 @@ int main(int argc, char *argv[]) {
int c;
int uid = -1, gid = -1;
int readiness = -1;
bool unlink_existing_socket = true;
bool chown_socket = true;
enum libseat_log_level level = LIBSEAT_LOG_LEVEL_ERROR;
const char *socket_path = SEATD_DEFAULTPATH;
while ((c = getopt(argc, argv, "vhn:s:g:u:l:")) != -1) {
while ((c = getopt(argc, argv, "vhn:g:u:l:z")) != -1) {
switch (c) {
case 'n':
readiness = atoi(optarg);
@ -82,10 +82,11 @@ int main(int argc, char *argv[]) {
return 1;
}
break;
case 's':
socket_path = optarg;
break;
case 'u': {
if (!chown_socket) {
fprintf(stderr, "-u/-g and -z are mutually exclusive\n");
return 1;
}
struct passwd *pw = getpwnam(optarg);
if (pw == NULL) {
fprintf(stderr, "Could not find user by name '%s'.\n", optarg);
@ -96,6 +97,10 @@ int main(int argc, char *argv[]) {
break;
}
case 'g': {
if (!chown_socket) {
fprintf(stderr, "-u/-g and -z are mutually exclusive\n");
return 1;
}
struct group *gr = getgrnam(optarg);
if (gr == NULL) {
fprintf(stderr, "Could not find group by name '%s'.\n", optarg);
@ -119,6 +124,17 @@ int main(int argc, char *argv[]) {
return 1;
}
break;
case 'z':
// Running under seatd-launch. We do not unlink files
// to protect against multiple instances, and
// seatd-launch takes care of ownership.
if (uid != -1 || gid != -1) {
fprintf(stderr, "-u/-g and -z are mutually exclusive\n");
return 1;
}
unlink_existing_socket = false;
chown_socket = false;
break;
case 'v':
printf("seatd version %s\n", SEATD_VERSION);
return 0;
@ -137,14 +153,19 @@ int main(int argc, char *argv[]) {
libseat_set_log_level(level);
struct stat st;
if (stat(socket_path, &st) == 0) {
if (lstat(SEATD_DEFAULTPATH, &st) == 0) {
if (!S_ISSOCK(st.st_mode)) {
log_errorf("Non-socket file found at socket path %s, refusing to start",
socket_path);
SEATD_DEFAULTPATH);
return 1;
} else if (!unlink_existing_socket) {
log_errorf("Socket file found at socket path %s, refusing to start",
SEATD_DEFAULTPATH);
return 1;
} else {
log_infof("Removing leftover socket at %s", socket_path);
if (unlink(socket_path) == -1) {
// We only do this if the socket path is not user specified
log_infof("Removing leftover socket at %s", SEATD_DEFAULTPATH);
if (unlink(SEATD_DEFAULTPATH) == -1) {
log_errorf("Could not remove leftover socket: %s", strerror(errno));
return 1;
}
@ -158,7 +179,7 @@ int main(int argc, char *argv[]) {
}
int ret = 1;
int socket_fd = open_socket(socket_path, uid, gid);
int socket_fd = open_socket(SEATD_DEFAULTPATH, uid, gid);
if (socket_fd == -1) {
log_error("Could not create server socket");
goto error_server;
@ -189,7 +210,7 @@ int main(int argc, char *argv[]) {
ret = 0;
error_socket:
if (unlink(socket_path) == -1) {
if (unlink(SEATD_DEFAULTPATH) == -1) {
log_errorf("Could not remove socket: %s", strerror(errno));
}
error_server:

Loading…
Cancel
Save