diff options
Diffstat (limited to 'mount.cifs.c')
-rw-r--r-- | mount.cifs.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/mount.cifs.c b/mount.cifs.c index aa5c9f9..c7954ce 100644 --- a/mount.cifs.c +++ b/mount.cifs.c @@ -43,6 +43,9 @@ #include <fstab.h> #include <sys/mman.h> #include <sys/wait.h> +#ifdef HAVE_LIBCAP +#include <sys/capability.h> +#endif /* HAVE_LIBCAP */ #include "mount.h" #include "util.h" @@ -1146,6 +1149,63 @@ add_mtab_exit: return rc; } +#ifdef HAVE_LIBCAP +static int +drop_capabilities(int parent) +{ + int rc = 0; + cap_t caps; + cap_value_t cap_list[2]; + + caps = cap_get_proc(); + if (caps == NULL) { + fprintf(stderr, "Unable to get current capability set: %s\n", + strerror(errno)); + return EX_SYSERR; + } + + if (cap_clear(caps) == -1) { + fprintf(stderr, "Unable to clear capability set: %s\n", + strerror(errno)); + rc = EX_SYSERR; + goto free_caps; + } + + /* parent needs to keep some capabilities */ + if (parent) { + cap_list[0] = CAP_SYS_ADMIN; + cap_list[1] = CAP_DAC_OVERRIDE; + if (cap_set_flag(caps, CAP_PERMITTED, 2, cap_list, CAP_SET) == -1) { + fprintf(stderr, "Unable to set permitted capabilities: %s\n", + strerror(errno)); + rc = EX_SYSERR; + goto free_caps; + } + if (cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET) == -1) { + fprintf(stderr, "Unable to set effective capabilities: %s\n", + strerror(errno)); + rc = EX_SYSERR; + goto free_caps; + } + } + + if (cap_set_proc(caps) != 0) { + fprintf(stderr, "Unable to set current process capabilities: %s\n", + strerror(errno)); + rc = EX_SYSERR; + } +free_caps: + cap_free(caps); + return rc; +} +#else /* HAVE_LIBCAP */ +static int +drop_capabilities(int parent) +{ + return 0; +} +#endif /* HAVE_LIBCAP */ + /* have the child drop root privileges */ static int drop_child_privs(void) @@ -1181,6 +1241,10 @@ assemble_mountinfo(struct parsed_mount_info *parsed_info, { int rc; + rc = drop_capabilities(0); + if (rc) + goto assemble_exit; + rc = drop_child_privs(); if (rc) goto assemble_exit; @@ -1292,6 +1356,10 @@ int main(int argc, char **argv) if (check_setuid()) return EX_USAGE; + rc = drop_capabilities(1); + if (rc) + return EX_SYSERR; + if (geteuid()) { fprintf(stderr, "%s: not installed setuid root - \"user\" " "CIFS mounts not supported.", thisprogram); |