Skip to content

Commit 7f7d84d

Browse files
committed
Use shadow as a fallback if PAM is unavailable
Allow building with PAM and/or shadow, instead of them build mutually exclusive. This allows producing a single binary which can be used on hosts with or without PAM installed.
1 parent 7682bf3 commit 7f7d84d

File tree

6 files changed

+95
-11
lines changed

6 files changed

+95
-11
lines changed

backend.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "swaylock.h"
2+
#include "log.h"
3+
#include "config.h"
4+
#include <stdlib.h>
5+
6+
#if !HAVE_PAM
7+
bool load_pam_library(void) {
8+
return false;
9+
}
10+
11+
bool is_pam_loaded(void) {
12+
return false;
13+
}
14+
15+
void initialize_pam_backend(int argc, char **argv) {
16+
// Stub function - should never be called
17+
}
18+
19+
void run_pam_backend_child(void) {
20+
// Stub function - should never be called
21+
}
22+
#endif
23+
24+
#if !HAVE_SHADOW
25+
void initialize_shadow_backend(int argc, char **argv) {
26+
// Stub function - should never be called
27+
}
28+
29+
void run_shadow_backend_child(void) {
30+
// Stub function - should never be called
31+
}
32+
#endif
33+
34+
void initialize_pw_backend(int argc, char **argv) {
35+
#if HAVE_PAM
36+
if (load_pam_library()) {
37+
swaylock_log(LOG_ERROR, "Initialising pam");
38+
initialize_pam_backend(argc, argv);
39+
return;
40+
}
41+
#endif
42+
#if HAVE_SHADOW
43+
swaylock_log(LOG_ERROR, "Initialising shadow");
44+
initialize_shadow_backend(argc, argv);
45+
#else
46+
swaylock_log(LOG_ERROR, "No authentication backend available");
47+
exit(EXIT_FAILURE);
48+
#endif
49+
}
50+
51+
void run_pw_backend_child(void) {
52+
#if HAVE_PAM
53+
if (is_pam_loaded()) {
54+
run_pam_backend_child();
55+
return;
56+
}
57+
#endif
58+
#if HAVE_SHADOW
59+
run_shadow_backend_child();
60+
#else
61+
swaylock_log(LOG_ERROR, "No authentication backend available");
62+
exit(EXIT_FAILURE);
63+
#endif
64+
}

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 & 1 deletion
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,19 @@ sources = [
108109

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

121+
if not libpam.found() and not get_option('shadow').enabled()
122+
error('At least one of PAM or shadow support must be enabled.')
123+
endif
124+
118125
swaylock_inc = include_directories('include')
119126

120127
executable('swaylock',
@@ -155,3 +162,8 @@ if scdoc.found()
155162
endif
156163

157164
subdir('completions')
165+
166+
summary({
167+
'pam': libpam.found(),
168+
'shadow': get_option('shadow').enabled(),
169+
}, 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)