diff --git a/include/swaylock.h b/include/swaylock.h index 32ded18..56cee3b 100644 --- a/include/swaylock.h +++ b/include/swaylock.h @@ -112,7 +112,7 @@ void damage_state(struct swaylock_state *state); void clear_password_buffer(struct swaylock_password *pw); void schedule_indicator_clear(struct swaylock_state *state); -void initialize_pw_backend(void); +void initialize_pw_backend(int argc, char **argv); void run_pw_backend_child(void); void clear_buffer(char *buf, size_t size); diff --git a/main.c b/main.c index 000b16a..d3921d5 100644 --- a/main.c +++ b/main.c @@ -977,7 +977,7 @@ static void comm_in(int fd, short mask, void *data) { int main(int argc, char **argv) { swaylock_log_init(LOG_ERROR); - initialize_pw_backend(); + initialize_pw_backend(argc, argv); enum line_mode line_mode = LM_LINE; state.args = (struct swaylock_args){ diff --git a/pam.c b/pam.c index 0c21536..a603bd8 100644 --- a/pam.c +++ b/pam.c @@ -11,7 +11,13 @@ static char *pw_buf = NULL; -void initialize_pw_backend(void) { +void initialize_pw_backend(int argc, char **argv) { + if (getuid() != geteuid() || getgid() != getegid()) { + swaylock_log(LOG_ERROR, + "swaylock is setuid, but was compiled with the PAM" + " backend. Run 'chmod a-s %s' to fix. Aborting.", argv[0]); + exit(EXIT_FAILURE); + } if (!spawn_comm_child()) { exit(EXIT_FAILURE); } diff --git a/shadow.c b/shadow.c index f98301e..70d00a8 100644 --- a/shadow.c +++ b/shadow.c @@ -12,6 +12,32 @@ #include "log.h" #include "swaylock.h" +void initialize_pw_backend(int argc, char **argv) { + if (geteuid() != 0) { + swaylock_log(LOG_ERROR, + "swaylock needs to be setuid to read /etc/shadow"); + exit(EXIT_FAILURE); + } + + if (!spawn_comm_child()) { + exit(EXIT_FAILURE); + } + + if (setgid(getgid()) != 0) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root"); + exit(EXIT_FAILURE); + } + if (setuid(getuid()) != 0) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root"); + exit(EXIT_FAILURE); + } + if (setuid(0) != -1) { + swaylock_log_errno(LOG_ERROR, "Unable to drop root (we shouldn't be " + "able to restore it after setuid)"); + exit(EXIT_FAILURE); + } +} + void run_pw_backend_child(void) { /* This code runs as root */ struct passwd *pwent = getpwuid(getuid()); @@ -72,30 +98,4 @@ void run_pw_backend_child(void) { clear_buffer(encpw, strlen(encpw)); exit(EXIT_SUCCESS); -} - -void initialize_pw_backend(void) { - if (geteuid() != 0) { - swaylock_log(LOG_ERROR, - "swaylock needs to be setuid to read /etc/shadow"); - exit(EXIT_FAILURE); - } - - if (!spawn_comm_child()) { - exit(EXIT_FAILURE); - } - - if (setgid(getgid()) != 0) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root"); - exit(EXIT_FAILURE); - } - if (setuid(getuid()) != 0) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root"); - exit(EXIT_FAILURE); - } - if (setuid(0) != -1) { - swaylock_log_errno(LOG_ERROR, "Unable to drop root (we shouldn't be " - "able to restore it after setuid)"); - exit(EXIT_FAILURE); - } -} +} \ No newline at end of file