diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2022-08-05 20:43:05 -0700 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2022-08-05 20:43:05 -0700 |
commit | fc437fd8308b4ee4d8e3053d51471883946f9b04 (patch) | |
tree | a0acacefad61ebe02dd3631237399caa1f465c34 | |
parent | 7db9589038d88b88111582da7681d33e1177f636 (diff) | |
download | libcap-fc437fd8308b4ee4d8e3053d51471883946f9b04.tar.gz |
Fix an issue with bash displaying an error.
Also down size the default capabilities needed by the 'sucap' su program.
This is aimed at addressing:
https://bugzilla.kernel.org/show_bug.cgi?id=215926
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r-- | contrib/sucap/Makefile | 12 | ||||
-rw-r--r-- | contrib/sucap/su.c | 43 |
2 files changed, 41 insertions, 14 deletions
diff --git a/contrib/sucap/Makefile b/contrib/sucap/Makefile index c58d5c4..df61ed5 100644 --- a/contrib/sucap/Makefile +++ b/contrib/sucap/Makefile @@ -1,12 +1,18 @@ topdir=$(shell pwd)/../.. include ../../Make.Rules +# This line is here to link against the in-tree copy of libcap.so +LINKEXTRA=-Wl,-rpath,$(topdir)/libcap +DEPS=../../libcap/libcap.so + all: su -su: su.c - $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DPAM_APP_NAME=\"sucap\" -o $@ $< -lpam -lpam_misc -lcap +su: su.c $(DEPS) + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DPAM_APP_NAME=\"sucap\" $< -o $@ $(LINKEXTRA) -lpam -lpam_misc $(LIBCAPLIB) # to permit all ambient capabilities, this needs all permitted. - sudo setcap =p ./su + # sudo setcap =p ./su + # to permit all inheritable, as CAP_PURE1E needs, we don't need as much + sudo setcap cap_chown,cap_setgid,cap_setuid,cap_dac_read_search,cap_setpcap=p ./su clean: rm -f su su.o *~ diff --git a/contrib/sucap/su.c b/contrib/sucap/su.c index c8cc05f..e3dfe70 100644 --- a/contrib/sucap/su.c +++ b/contrib/sucap/su.c @@ -149,20 +149,26 @@ static void checkfds(void) if (fstat(1, &st) == -1) { fd = open("/dev/null", O_WRONLY); - if (fd == -1) exit(1); + if (fd == -1) goto badfds; if (fd != 1) { - if (dup2(fd, 1) == -1) exit(1); - if (close(fd) == -1) exit(1); + if (dup2(fd, 1) == -1) goto badfds; + if (close(fd) == -1) goto badfds; } } if (fstat(2, &st) == -1) { fd = open("/dev/null", O_WRONLY); - if (fd == -1) exit(1); + if (fd == -1) goto badfds; if (fd != 2) { - if (dup2(fd, 2) == -1) exit(1); - if (close(fd) == -1) exit(1); + if (dup2(fd, 2) == -1) goto badfds; + if (close(fd) == -1) goto badfds; } } + + return; + +badfds: + perror("bad filedes"); + exit(1); } /* @@ -1210,6 +1216,11 @@ static int set_credentials(cap_t all, int login, } uid = pw->pw_uid; + if (uid == 0) { + D(("user is superuser: %s", user)); + *retval = PAM_CRED_ERR; + return 1; + } *uid_p = uid; shell = x_strdup(pw->pw_shell); @@ -1226,11 +1237,18 @@ static int set_credentials(cap_t all, int login, *retval = PAM_CRED_ERR; return 1; } - if (pam_misc_setenv(pamh, "HOME", pw->pw_dir, 0) != PAM_SUCCESS) { - D(("failed to set HOME")); - *retval = PAM_CRED_ERR; - return 1; - } + } + + /* bash requires these be set to the target user values */ + if (pam_misc_setenv(pamh, "HOME", pw->pw_dir, 0) != PAM_SUCCESS) { + D(("failed to set HOME")); + *retval = PAM_CRED_ERR; + return 1; + } + if (pam_misc_setenv(pamh, "USER", user, 0) != PAM_SUCCESS) { + D(("failed to set USER")); + *retval = PAM_CRED_ERR; + return 1; } current = cap_get_proc(); @@ -1613,5 +1631,8 @@ auth_exit: } su_exit: + if (status != 0) { + perror(PAM_APP_NAME " failed"); + } exit(status); /* transparent exit */ } |