From 85748f41a73ea18241a7291a8d4a29e06377cd79 Mon Sep 17 00:00:00 2001 From: "Andrew G. Morgan" Date: Sun, 8 Aug 2010 17:42:11 -0700 Subject: Default to installing setcap with an inheritable capability. For my conveneince, default to installing an inheritable file capability on setcap when installed. This requires the process inherit a capability for it to take effect, but that's what pam_cap is for... You can disable this install feature with: make RAISE_SETFCAP=no install Also, clean up Make files and a test, and add more comments. The make files needed a fix (remove -lpam from pam_cap/Makefile) and I've added a number of comments in support of various issues folk have asked me about. Signed-off-by: Andrew G. Morgan --- Make.Rules | 12 ++++++++++++ pam_cap/Makefile | 6 +++++- pam_cap/capability.conf | 24 ++++++++++++++++++++---- progs/Makefile | 3 +++ progs/capsh.c | 6 +++++- progs/quicktest.sh | 2 +- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/Make.Rules b/Make.Rules index c0f8b55..011aa14 100644 --- a/Make.Rules +++ b/Make.Rules @@ -9,6 +9,8 @@ FAKEROOT=$(DESTDIR) # Autoconf-style prefixes are activated when $(prefix) is defined. # Otherwise binaries and libraraies are installed in /{lib,sbin}/, # header files in /usr/include/ and documentation in /usr/man/man?/. +# These choices are motivated by the fact that getcap and setcap are +# administrative operations that could be needed to recover a system. ifndef lib lib=$(shell ldd /usr/bin/ld|fgrep ld-linux|cut -d/ -f2) @@ -68,6 +70,16 @@ INDENT := $(shell if [ -n "$(which indent 2>/dev/null)" ]; then echo "| indent - DYNAMIC := $(shell if [ ! -d "$(topdir)/.git" ]; then echo yes; fi) LIBATTR := yes +# When installing setcap, set its inheritable bit to be able to place +# capabilities on files. It can be used in conjunction with pam_cap +# (associated with su and certain users say) to make it useful for +# specially blessed users. If you wish to drop this install feature, +# use this command when running install +# +# make RAISE_SETFCAP=no install +# +RAISE_SETFCAP := $(LIBATTR) + # Global cleanup stuff LOCALCLEAN=rm -f *~ core diff --git a/pam_cap/Makefile b/pam_cap/Makefile index 397a7cc..9ca5bef 100644 --- a/pam_cap/Makefile +++ b/pam_cap/Makefile @@ -3,7 +3,11 @@ topdir=$(shell pwd)/.. include ../Make.Rules -LDLIBS += -L../libcap -lcap -lpam +# Note (as the author of much of the Linux-PAM library, I am confident +# that this next line does *not* require -lpam on it.) If you think it +# does, *verify that it does*, and if you observe that it fails as +# written (and you know why it fails), email me and explain why. Thanks! +LDLIBS += -L../libcap -lcap all: pam_cap.so $(MAKE) testcompile diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index 0685b2e..dd93ea7 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -15,15 +15,31 @@ # Here are some sample lines (remove the preceding '#' if you want to # use them -## user 'morgan' gets the CAP_SETFCAP inheritable capability +## user 'morgan' gets the CAP_SETFCAP inheritable capability (commented out!) #cap_setfcap morgan -## user 'luser' inherits the CAP_DAC_OVERRIDE capability +## user 'luser' inherits the CAP_DAC_OVERRIDE capability (commented out!) #cap_dac_override luser -## 'everyone else' gets no inheritable capabilities +## 'everyone else' gets no inheritable capabilities (restrictive config) none * ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and -## probably not what you want... +## possibly not what you want... On first reading, you might think this +## is a security problem waiting to happen, but it defaults to not being +## so in this sample file! Further, by 'get', we mean 'get in their inheritable +## set'. That is, if you look at a random process, even one run by root, +## you will see it has no inheritable capabilities (by default): +## +## $ /sbin/capsh --decode=$(grep CapInh /proc/1/status|awk '{print $2}') +## 0000000000000000= +## +## The pam_cap module simply alters the value of this capability +## set. Including the 'none *' forces use of this module with an +## unspecified user to have their inheritable set forced to zero. +## +## Omitting the line will cause the inheritable set to be unmodified +## from what the parent process had (which is generally 0 unless the +## invoking user was bestowed with some inheritable capabilities by a +## previous invocation). diff --git a/progs/Makefile b/progs/Makefile index 8000a91..ef51dc6 100644 --- a/progs/Makefile +++ b/progs/Makefile @@ -29,6 +29,9 @@ install: all for p in $(PROGS) ; do \ install -m 0755 $$p $(SBINDIR) ; \ done +ifeq ($(RAISE_SETFCAP),yes) + $(SBINDIR)/setcap cap_setfcap=i $(SBINDIR)/setcap +endif clean: $(LOCALCLEAN) diff --git a/progs/capsh.c b/progs/capsh.c index 9645807..b1eb549 100644 --- a/progs/capsh.c +++ b/progs/capsh.c @@ -152,7 +152,11 @@ int main(int argc, char *argv[], char *envp[]) perror("Out of memory for inh set"); exit(1); } - sprintf(ptr, "%s %s+i", text, argv[i]+6); + if (argv[i][6] && strcmp("none", argv[i]+6)) { + sprintf(ptr, "%s %s+i", text, argv[i]+6); + } else { + strcpy(ptr, text); + } all = cap_from_text(ptr); if (all == NULL) { diff --git a/progs/quicktest.sh b/progs/quicktest.sh index 0297bee..5959da9 100755 --- a/progs/quicktest.sh +++ b/progs/quicktest.sh @@ -121,7 +121,7 @@ fi exit 0 EOF chmod +xs hack.sh -./capsh --uid=500 -- ./hack.sh +./capsh --uid=500 --inh=none --print -- ./hack.sh status=$? rm -f ./hack.sh if [ $status -ne 0 ]; then -- cgit v1.2.1