Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 921584
Collapse All | Expand All

(-)a/shadow.c (-1 / +59 lines)
Lines 1-9 Link Here
1
#define _XOPEN_SOURCE // for crypt
1
#define _XOPEN_SOURCE // for crypt
2
#define _DEFAULT_SOURCE // syscall
2
#include <pwd.h>
3
#include <pwd.h>
3
#include <shadow.h>
4
#include <shadow.h>
4
#include <stdlib.h>
5
#include <stdlib.h>
5
#include <stdbool.h>
6
#include <stdbool.h>
6
#include <sys/types.h>
7
#include <sys/types.h>
8
#include <linux/capability.h>
9
#include <sys/syscall.h>
10
#include <fcntl.h>
7
#include <unistd.h>
11
#include <unistd.h>
8
#ifdef __GLIBC__
12
#ifdef __GLIBC__
9
// GNU, you damn slimy bastard
13
// GNU, you damn slimy bastard
Lines 15-25 Link Here
15
#include "swaylock.h"
18
#include "swaylock.h"
16
19
17
void initialize_pw_backend(int argc, char **argv) {
20
void initialize_pw_backend(int argc, char **argv) {
18
	if (geteuid() != 0) {
21
	int fd_shadow = open("/etc/shadow", O_CLOEXEC | O_RDONLY);
22
	if (geteuid() != 0 && fd_shadow == -1) {
19
		swaylock_log(LOG_ERROR,
23
		swaylock_log(LOG_ERROR,
20
				"swaylock needs to be setuid to read /etc/shadow");
24
				"swaylock needs to be setuid to read /etc/shadow");
21
		exit(EXIT_FAILURE);
25
		exit(EXIT_FAILURE);
22
	}
26
	}
27
	if (fd_shadow != -1)
28
		close(fd_shadow);
23
	if (!spawn_comm_child()) {
29
	if (!spawn_comm_child()) {
24
		exit(EXIT_FAILURE);
30
		exit(EXIT_FAILURE);
Lines 38-43 void initialize_pw_backend(int argc, cha Link Here
38
			"able to restore it after setuid)");
41
			"able to restore it after setuid)");
39
		exit(EXIT_FAILURE);
42
		exit(EXIT_FAILURE);
40
	}
43
	}
44
	fd_shadow = open("/etc/shadow", O_CLOEXEC | O_RDONLY);
45
	if (fd_shadow != -1) {
46
		cap_user_header_t hdrp = alloca(sizeof(*hdrp));
47
		cap_user_data_t datap = alloca(2 * sizeof(*datap));
48
		int ret;
49
50
		close(fd_shadow);
51
		memset(hdrp, 0, sizeof(*hdrp));
52
		hdrp->version = _LINUX_CAPABILITY_VERSION_3;
53
		ret = syscall(SYS_capget, hdrp, datap);
54
		if (ret != 0) {
55
			swaylock_log_errno(LOG_ERROR, "Unable to verify capabilities");
56
			exit(EXIT_FAILURE);
57
		} else if (datap[0].effective != 0 || datap[0].permitted != 0 || datap[0].inheritable != 0 ||
58
			datap[1].effective != 0 || datap[1].permitted != 0 || datap[1].inheritable != 0) {
59
			memset(datap, 0, 2 * sizeof(*datap));
60
			ret = syscall(SYS_capset, hdrp, datap);
61
			if (ret != 0) {
62
				swaylock_log_errno(LOG_ERROR, "Unable to drop capabilities");
63
				exit(EXIT_FAILURE);
64
			}
65
		}
66
	}
67
	fd_shadow = open("/etc/shadow", O_CLOEXEC | O_RDONLY);
68
	if (fd_shadow != -1) {
69
		swaylock_log(LOG_ERROR, "Still able to read /etc/shadow");
70
		exit(EXIT_FAILURE);
71
	}
41
}
72
}
42
73
43
void run_pw_backend_child(void) {
74
void run_pw_backend_child(void) {
Lines 68-73 void run_pw_backend_child(void) { Link Here
68
	if (setuid(0) != -1) {
92
	if (setuid(0) != -1) {
69
		exit(EXIT_FAILURE);
93
		exit(EXIT_FAILURE);
70
	}
94
	}
95
	int fd_shadow = open("/etc/shadow", O_CLOEXEC | O_RDONLY);
96
	if (fd_shadow != -1) {
97
		cap_user_header_t hdrp = alloca(sizeof(*hdrp));
98
		cap_user_data_t datap = alloca(2 * sizeof(*datap));
99
		int ret;
100
101
		close(fd_shadow);
102
		memset(hdrp, 0, sizeof(*hdrp));
103
		hdrp->version = _LINUX_CAPABILITY_VERSION_3;
104
		ret = syscall(SYS_capget, hdrp, datap);
105
		if (ret != 0) {
106
			swaylock_log_errno(LOG_ERROR, "Unable to verify capabilities");
107
			exit(EXIT_FAILURE);
108
		} else if (datap[0].effective != 0 || datap[0].permitted != 0 || datap[0].inheritable != 0 ||
109
			datap[1].effective != 0 || datap[1].permitted != 0 || datap[1].inheritable != 0) {
110
			memset(datap, 0, 2 * sizeof(*datap));
111
			ret = syscall(SYS_capset, hdrp, datap);
112
			if (ret != 0) {
113
				swaylock_log_errno(LOG_ERROR, "Unable to drop capabilities");
114
				exit(EXIT_FAILURE);
115
			}
116
		}
117
	}
71
118
72
	/* This code does not run as root */
119
	/* This code does not run as root */
73
	swaylock_log(LOG_DEBUG, "Prepared to authorize user %s", pwent->pw_name);
120
	swaylock_log(LOG_DEBUG, "Prepared to authorize user %s", pwent->pw_name);

Return to bug 921584