Skip to content

Commit fc3e75b

Browse files
committed
Use shadow as a fallback if PAM is unavailable
1 parent 7682bf3 commit fc3e75b

File tree

6 files changed

+51
-12
lines changed

6 files changed

+51
-12
lines changed

backend.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "swaylock.h"
2+
#include "log.h"
3+
4+
void initialize_pw_backend(int argc, char **argv) {
5+
if (load_pam_library()) {
6+
swaylock_log(LOG_ERROR, "Initialising pam");
7+
initialize_pam_backend(argc, argv);
8+
} else {
9+
swaylock_log(LOG_ERROR, "Initialising shadow");
10+
initialize_shadow_backend(argc, argv);
11+
}
12+
}
13+
14+
void run_pw_backend_child(void) {
15+
if (is_pam_loaded()) {
16+
run_pam_backend_child();
17+
} else {
18+
run_shadow_backend_child();
19+
}
20+
}

include/swaylock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,15 @@ void damage_state(struct swaylock_state *state);
140140
void clear_password_buffer(struct swaylock_password *pw);
141141
void schedule_auth_idle(struct swaylock_state *state);
142142

143+
bool load_pam_library(void);
144+
bool is_pam_loaded(void);
145+
143146
void initialize_pw_backend(int argc, char **argv);
147+
void initialize_pam_backend(int argc, char **argv);
148+
void initialize_shadow_backend(int argc, char **argv);
144149
void run_pw_backend_child(void);
150+
void run_pam_backend_child(void);
151+
void run_shadow_backend_child(void);
145152
void clear_buffer(char *buf, size_t size);
146153

147154
#endif

meson.build

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ dependencies = [
9393

9494
sources = [
9595
'background-image.c',
96+
'backend.c',
9697
'cairo.c',
9798
'comm.c',
9899
'log.c',
@@ -108,13 +109,18 @@ sources = [
108109

109110
if libpam.found()
110111
sources += ['pam.c']
111-
else
112-
warning('The swaylock binary must be setuid when compiled without libpam')
112+
endif
113+
if get_option('shadow').enabled()
114+
warning('The swaylock binary must be setuid when used without libpam')
113115
warning('You must do this manually post-install: chmod a+s /path/to/swaylock')
114116
sources += ['shadow.c']
115117
dependencies += [crypt]
116118
endif
117119

120+
if not libpam.found() and not get_option('shadow').enabled()
121+
error('Either PAM or shadow support must be enabled.')
122+
endif
123+
118124
swaylock_inc = include_directories('include')
119125

120126
executable('swaylock',
@@ -155,3 +161,8 @@ if scdoc.found()
155161
endif
156162

157163
subdir('completions')
164+
165+
summary({
166+
'pam': libpam.found(),
167+
'shadow': get_option('shadow').enabled(),
168+
}, bool_yn: true)

meson_options.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
option('pam', type: 'feature', value: 'auto', description: 'Use PAM instead of shadow')
1+
option('pam', type: 'feature', value: 'auto', description: 'Enabled PAM support')
2+
option('shadow', type: 'feature', value: 'auto', description: 'Enabled shadow support')
23
option('gdk-pixbuf', type: 'feature', value: 'auto', description: 'Enable support for more image formats')
34
option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
45
option('zsh-completions', type: 'boolean', value: true, description: 'Install zsh shell completions')

pam.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static int (*fp_pam_authenticate)(pam_handle_t *, int) = NULL;
2121
static int (*fp_pam_end)(pam_handle_t *, int) = NULL;
2222
static int (*fp_pam_setcred)(pam_handle_t *, int) = NULL;
2323

24-
static bool load_pam_library(void) {
24+
bool load_pam_library(void) {
2525
pam_handle = dlopen("libpam.so.0", RTLD_NOW);
2626
if (!pam_handle) {
2727
swaylock_log(LOG_ERROR, "Failed to load libpam.so.0: %s", dlerror());
@@ -42,14 +42,18 @@ static bool load_pam_library(void) {
4242
return true;
4343
}
4444

45+
bool is_pam_loaded(void) {
46+
return pam_handle != NULL;
47+
}
48+
4549
static void unload_pam_library(void) {
4650
if (pam_handle) {
4751
dlclose(pam_handle);
4852
pam_handle = NULL;
4953
}
5054
}
5155

52-
void initialize_pw_backend(int argc, char **argv) {
56+
void initialize_pam_backend(int argc, char **argv) {
5357
if (getuid() != geteuid() || getgid() != getegid()) {
5458
swaylock_log(LOG_ERROR,
5559
"swaylock is setuid, but was compiled with the PAM"
@@ -107,11 +111,7 @@ static const char *get_pam_auth_error(int pam_status) {
107111
}
108112
}
109113

110-
void run_pw_backend_child(void) {
111-
if (!load_pam_library()) {
112-
exit(EXIT_FAILURE); // Fall back or exit if desired
113-
}
114-
114+
void run_pam_backend_child(void) {
115115
struct passwd *passwd = getpwuid(getuid());
116116
if (!passwd) {
117117
swaylock_log_errno(LOG_ERROR, "getpwuid failed");

shadow.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
char *encpw = NULL;
2020

21-
void initialize_pw_backend(int argc, char **argv) {
21+
void initialize_shadow_backend(int argc, char **argv) {
2222
/* This code runs as root */
2323
struct passwd *pwent = getpwuid(getuid());
2424
if (!pwent) {
@@ -61,7 +61,7 @@ void initialize_pw_backend(int argc, char **argv) {
6161
encpw = NULL;
6262
}
6363

64-
void run_pw_backend_child(void) {
64+
void run_shadow_backend_child(void) {
6565
assert(encpw != NULL);
6666
while (1) {
6767
char *buf;

0 commit comments

Comments
 (0)