Skip to content

Commit c8858c8

Browse files
committed
pam_tcb: Add support for user authentication with SELinux.
NSA Security-Enhanced Linux (SELinux) is an implementation of a flexible mandatory access control architecture in the Linux operating system. Background information and technical documentation about SELinux can be found at https://github.com/SELinuxProject. With SELinux running in enforced mode even read-access to the shadow files, which the hashed user passwords are stored in, is restricted to processes that have at least been granted "shadow_t:file read" capabilites by the SELinux policy. For that reason the login authentication of a user must always be performed by the "tcb_chkpwd" helper binary. Signed-off-by: Björn Esser <[email protected]>
1 parent 070cf4a commit c8858c8

File tree

7 files changed

+60
-4
lines changed

7 files changed

+60
-4
lines changed

ChangeLog

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
2021-10-08 Björn Esser <besser82 at fedoraproject.org>
2+
3+
pam_tcb: Add support for user authentication with SELinux.
4+
With SELinux running in enforced mode even read-access to
5+
the shadow files, which the hashed user passwords are stored
6+
in, is restricted to processes that have at least been granted
7+
"shadow_t:file read" capabilites by the SELinux policy. For
8+
that reason the login authentication of a user must always be
9+
performed by the "tcb_chkpwd" helper binary.
10+
* pam_tcb/support.c (unix_verify_password_plain): Use the chkpwd
11+
helper binary to verify the user's password if SELinux is enabled,
12+
and prevents read-access to the file storing the hashed password.
13+
* pam_tcb/support.h (SELINUX_ENABLED): Include <selinux/selinux.h>
14+
if support for SELinux is requested. Also define SELINUX_ENABLED.
15+
* progs/tcb_chkpwd.c (SELINUX_ENABLED): Likewise.
16+
* progs/tcb_chkpwd.c (unix_verify_password): Do not fail during
17+
authentication when SELinux is enabled and the UID of the user to
18+
be authenticated differs from the UID of the actual caller.
19+
* Make.defs: Add flag to (optionally) enable support for SELinux.
20+
* pam_tcb/Makefile: Apply the needed pre-processor define
21+
and link against libselinux if support for SELinux is requested.
22+
* progs/Makefile: Likewise.
23+
124
2021-09-30 Björn Esser <besser82 at fedoraproject.org>
225

326
pam_tcb: Fix "-Wpedantic".

Make.defs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ MKDIR = mkdir
55
# Flag to enable -Werror on build.
66
WERROR =
77

8+
# Flag to enable support for SELinux in pam_tcb.
9+
ENABLE_SELINUX =
10+
811
DBGFLAG = #-ggdb
912
ifndef CFLAGS
1013
CFLAGS = -O2

pam_tcb/Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ ifneq ($(PAM_SO_SUFFIX),)
88
PAM_TCB_SONAME = -Wl,-soname,$(PAM_TCB)
99
endif
1010

11+
PAM_TCB_LIBS = -lcrypt -lpam
12+
13+
ifneq ($(ENABLE_SELINUX),)
14+
CFLAGS += -DWITH_SELINUX
15+
PAM_TCB_LIBS += -lselinux
16+
endif
17+
18+
PAM_TCB_LIBS += -ltcb
19+
1120
LIBSRC = \
1221
pam_unix_auth.c pam_unix_acct.c pam_unix_sess.c pam_unix_passwd.c \
1322
support.c compat.c
@@ -18,7 +27,7 @@ all: $(PAM_TCB)
1827

1928
$(PAM_TCB): $(LIBOBJ) $(PAM_MAP)
2029
$(CC) $(LDFLAGS) -shared -o $@ $(PAM_TCB_SONAME) \
21-
-Wl,--version-script=$(PAM_MAP) $(LIBOBJ) -lcrypt -lpam -ltcb
30+
-Wl,--version-script=$(PAM_MAP) $(LIBOBJ) $(PAM_TCB_LIBS)
2231

2332
.c.o:
2433
$(CC) $(CFLAGS) -fPIC -c $< -o $@

pam_tcb/support.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ static int unix_verify_password_plain(pam_handle_t *pamh,
475475
if (!salt) {
476476
/* we're not faking, we have an existing user, so... */
477477
uid_t uid = getuid();
478-
if (uid == geteuid() && uid == pw->pw_uid && uid != 0) {
478+
if (SELINUX_ENABLED || (uid == geteuid() && uid == pw->pw_uid && uid != 0)) {
479479
/* We are not root perhaps this is the reason? */
480480
D(("running helper binary"));
481481
retval = unix_run_helper_binary(user, pass);

pam_tcb/support.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212
# include "compat.h"
1313
#endif
1414

15+
#ifdef WITH_SELINUX
16+
#include <selinux/selinux.h>
17+
#define SELINUX_ENABLED (is_selinux_enabled()>0)
18+
#else
19+
#define SELINUX_ENABLED 0
20+
#endif /* WITH_SELINUX */
21+
1522
#if defined(ENABLE_NLS) && defined(NLS_PACKAGE)
1623
#include <libintl.h>
1724
#define _(msgid) dgettext(NLS_PACKAGE, msgid)

progs/Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ CONVERT = tcb_convert
44
UNCONVERT = tcb_unconvert
55
CHKPWD = tcb_chkpwd
66

7+
CHKPWD_LIBS += -lcrypt
8+
9+
ifneq ($(ENABLE_SELINUX),)
10+
CFLAGS += -DWITH_SELINUX
11+
CHKPWD_LIBS += -lselinux
12+
endif
13+
714
all: $(CONVERT) $(UNCONVERT) $(CHKPWD)
815

916
$(CONVERT): $(CONVERT).o
@@ -13,7 +20,7 @@ $(UNCONVERT): $(UNCONVERT).o
1320
$(CC) $(LDFLAGS) -o $@ $< -ltcb
1421

1522
$(CHKPWD): $(CHKPWD).o
16-
$(CC) $(LDFLAGS) -o $@ $< -lcrypt
23+
$(CC) $(LDFLAGS) -o $@ $< $(CHKPWD_LIBS)
1724

1825
.c.o:
1926
$(CC) $(CFLAGS) -c $< -o $@

progs/tcb_chkpwd.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
#include <pwd.h>
1616
#include <shadow.h>
1717

18+
#ifdef WITH_SELINUX
19+
#include <selinux/selinux.h>
20+
#define SELINUX_ENABLED (is_selinux_enabled()>0)
21+
#else
22+
#define SELINUX_ENABLED 0
23+
#endif /* WITH_SELINUX */
24+
1825
#include "_tcb.h"
1926

2027
IO_LOOP(read_loop, read,)
@@ -43,7 +50,7 @@ static int unix_verify_password(const char *user, const char *pass, int nullok)
4350

4451
stored_hash = NULL;
4552
if (pw) {
46-
if (getuid() != pw->pw_uid)
53+
if (!SELINUX_ENABLED && getuid() != pw->pw_uid)
4754
return AUTH_FAILED;
4855

4956
if (!strcmp(pw->pw_passwd, "x")) {

0 commit comments

Comments
 (0)