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.
This commit is contained in:
Kenny Levinsen 2022-02-26 20:25:22 +01:00
parent 466efea49b
commit 0d6bdf4f01
4 changed files with 43 additions and 29 deletions

View file

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

View file

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

View file

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

View file

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