mirror of
https://github.com/javalsai/lidm.git
synced 2025-08-31 02:18:00 +02:00
feat: better spawn error handling
This commit is contained in:
77
src/auth.c
77
src/auth.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <errno.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <security/pam_misc.h>
|
#include <security/pam_misc.h>
|
||||||
@@ -81,6 +82,12 @@ void source_paths(struct Vector* NNULLABLE vec_envlist,
|
|||||||
/*setenv("XDG_SESSION_DESKTOP", , true);*/
|
/*setenv("XDG_SESSION_DESKTOP", , true);*/
|
||||||
/*setenv("XDG_SEAT", "seat0", true);*/
|
/*setenv("XDG_SEAT", "seat0", true);*/
|
||||||
|
|
||||||
|
struct child_msg {
|
||||||
|
char* msg;
|
||||||
|
int _errno;
|
||||||
|
bool err;
|
||||||
|
};
|
||||||
|
|
||||||
// NOLINTBEGIN(readability-function-cognitive-complexity)
|
// NOLINTBEGIN(readability-function-cognitive-complexity)
|
||||||
bool launch(char* user, char* passwd, struct session session, void (*cb)(void),
|
bool launch(char* user, char* passwd, struct session session, void (*cb)(void),
|
||||||
struct config* config) {
|
struct config* config) {
|
||||||
@@ -134,45 +141,67 @@ bool launch(char* user, char* passwd, struct session session, void (*cb)(void),
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pipefd[2];
|
||||||
|
pipe(pipefd);
|
||||||
|
|
||||||
uint pid = fork();
|
uint pid = fork();
|
||||||
if (pid == 0) { // child
|
if (pid == 0) { // child
|
||||||
if (chdir(pw->pw_dir) == -1) print_errno("can't chdir to user home");
|
|
||||||
|
|
||||||
// TODO: chown stdin to user
|
#define SEND_MSG(MSG) \
|
||||||
// does it inherit stdin from parent and
|
{ \
|
||||||
// does parent need to reclaim it after
|
write(pipefd[1], &(MSG), sizeof(struct child_msg)); \
|
||||||
// this dies?
|
close(pipefd[1]); \
|
||||||
|
}
|
||||||
|
#define SEND_ERR(MSG) \
|
||||||
|
{ \
|
||||||
|
write(pipefd[1], \
|
||||||
|
&(struct child_msg){.msg = (MSG), ._errno = errno, .err = true}, \
|
||||||
|
sizeof(struct child_msg)); \
|
||||||
|
close(pipefd[1]); \
|
||||||
|
_exit(EXIT_FAILURE); \
|
||||||
|
}
|
||||||
|
|
||||||
if (setgid(pw->pw_gid) == -1) {
|
if (chdir(pw->pw_dir) == -1) SEND_ERR("chdir");
|
||||||
print_errno("setgid");
|
if (setgid(pw->pw_gid) == -1) SEND_ERR("setgid");
|
||||||
_exit(EXIT_FAILURE);
|
if (initgroups(user, pw->pw_gid) == -1) SEND_ERR("initgroups");
|
||||||
}
|
if (setuid(pw->pw_uid) == -1) SEND_ERR("setuid");
|
||||||
if (initgroups(user, pw->pw_gid) == -1) {
|
|
||||||
print_errno("initgroups");
|
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setuid(pw->pw_uid) == -1) {
|
SEND_MSG((struct child_msg){.err = false});
|
||||||
perror("setuid");
|
#undef SEND_MSG
|
||||||
_exit(EXIT_FAILURE);
|
#undef SEND_ERR
|
||||||
}
|
char _;
|
||||||
|
read(pipefd[0], &_, sizeof(_));
|
||||||
|
close(pipefd[0]);
|
||||||
|
|
||||||
if (cb) cb();
|
int exit;
|
||||||
|
|
||||||
printf("\x1b[0m\x1b[H\x1b[J");
|
|
||||||
(void)fflush(stdout);
|
|
||||||
if (session.type == SHELL) {
|
if (session.type == SHELL) {
|
||||||
execle(session.exec, session.exec, NULL, envlist);
|
exit = execle(session.exec, session.exec, NULL, envlist);
|
||||||
} else if (session.type == XORG || session.type == WAYLAND) {
|
} else if (session.type == XORG || session.type == WAYLAND) {
|
||||||
// TODO: test existence of executable with TryExec
|
// TODO: test existence of executable with TryExec
|
||||||
// NOLINTNEXTLINE
|
// NOLINTNEXTLINE
|
||||||
execve(desktop_exec[0], desktop_exec, envlist);
|
exit = execve(desktop_exec[0], desktop_exec, envlist);
|
||||||
// NOLINTNEXTLINE
|
// NOLINTNEXTLINE
|
||||||
free_parsed_args(desktop_count, desktop_exec);
|
free_parsed_args(desktop_count, desktop_exec);
|
||||||
}
|
} else
|
||||||
|
exit = -1;
|
||||||
perror("exec error");
|
perror("exec error");
|
||||||
(void)fputs("failure calling session\n", stderr);
|
(void)fputs("failure calling session\n", stderr);
|
||||||
|
_exit(exit);
|
||||||
} else {
|
} else {
|
||||||
|
struct child_msg msg;
|
||||||
|
read(pipefd[0], &msg, sizeof(struct child_msg));
|
||||||
|
close(pipefd[0]);
|
||||||
|
if (msg.err) {
|
||||||
|
errno = msg._errno;
|
||||||
|
print_errno(msg.msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb) cb();
|
||||||
|
printf("\x1b[0m\x1b[H\x1b[J");
|
||||||
|
(void)fflush(stdout);
|
||||||
|
close(pipefd[1]);
|
||||||
|
|
||||||
int exit_code;
|
int exit_code;
|
||||||
waitpid((pid_t)pid, &exit_code, 0);
|
waitpid((pid_t)pid, &exit_code, 0);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user