summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--cifs.upcall.c64
2 files changed, 65 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 2e99e60..4823b63 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,7 +16,7 @@ clean-local: clean-local-upcall clean-local-idmap clean-local-cifsacl
if CONFIG_CIFSUPCALL
sbin_PROGRAMS += cifs.upcall
cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c
-cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD)
+cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) $(CAPNG_LDADD)
man_MANS += cifs.upcall.8
#
diff --git a/cifs.upcall.c b/cifs.upcall.c
index 2b535a1..0bd3dcb 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -54,6 +54,10 @@
#include "spnego.h"
#include "cifs_spnego.h"
+#ifdef HAVE_LIBCAP_NG
+#include <cap-ng.h>
+#endif
+
static krb5_context context;
static const char *prog = "cifs.upcall";
@@ -63,6 +67,59 @@ typedef enum _sectype {
MS_KRB5
} sectype_t;
+#ifdef HAVE_LIBCAP_NG
+static int
+trim_capabilities(bool need_ptrace)
+{
+ capng_clear(CAPNG_SELECT_BOTH);
+
+ /*
+ * Need PTRACE and DAC_OVERRIDE for environment scraping, SETGID to
+ * change gid and grouplist, and SETUID to change uid.
+ */
+ if (capng_updatev(CAPNG_ADD, CAPNG_PERMITTED|CAPNG_EFFECTIVE,
+ CAP_SETUID, CAP_SETGID, CAP_DAC_OVERRIDE, -1)) {
+ syslog(LOG_ERR, "%s: Unable to update capability set: %m\n", __func__);
+ return 1;
+ }
+
+ if (need_ptrace &&
+ capng_update(CAPNG_ADD, CAPNG_PERMITTED|CAPNG_EFFECTIVE, CAP_SYS_PTRACE)) {
+ syslog(LOG_ERR, "%s: Unable to update capability set: %m\n", __func__);
+ return 1;
+ }
+
+ if (capng_apply(CAPNG_SELECT_BOTH)) {
+ syslog(LOG_ERR, "%s: Unable to apply capability set: %m\n", __func__);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+drop_all_capabilities(void)
+{
+ capng_clear(CAPNG_SELECT_BOTH);
+ if (capng_apply(CAPNG_SELECT_BOTH)) {
+ syslog(LOG_ERR, "%s: Unable to apply capability set: %m\n", __func__);
+ return 1;
+ }
+ return 0;
+}
+#else /* HAVE_LIBCAP_NG */
+static int
+trim_capabilities(void)
+{
+ return 0;
+}
+
+static int
+drop_all_capabilities(void)
+{
+ return 0;
+}
+#endif /* HAVE_LIBCAP_NG */
+
/*
* smb_krb5_principal_get_realm
*
@@ -733,6 +790,9 @@ int main(const int argc, char *const argv[])
}
}
+ if (trim_capabilities(false))
+ goto out;
+
/* is there a key? */
if (argc <= optind) {
usage();
@@ -837,6 +897,10 @@ int main(const int argc, char *const argv[])
goto out;
}
+ rc = drop_all_capabilities();
+ if (rc)
+ goto out;
+
rc = krb5_init_context(&context);
if (rc) {
syslog(LOG_ERR, "unable to init krb5 context: %ld", rc);