summaryrefslogtreecommitdiff
path: root/mount.cifs.c
diff options
context:
space:
mode:
Diffstat (limited to 'mount.cifs.c')
-rw-r--r--mount.cifs.c210
1 files changed, 144 insertions, 66 deletions
diff --git a/mount.cifs.c b/mount.cifs.c
index 7d1fa83..1f08230 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -322,21 +322,142 @@ static int parse_username(char *rawuser, struct parsed_mount_info *parsed_info)
return 0;
}
+#ifdef HAVE_LIBCAP
+static int
+drop_capabilities(int parent)
+{
+ int rc = 0, ncaps;
+ 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;
+ }
+
+ if (parent || getuid() == 0) {
+ ncaps = 1;
+ cap_list[0] = CAP_DAC_OVERRIDE;
+ if (parent) {
+ cap_list[1] = CAP_SYS_ADMIN;
+ ++ncaps;
+ }
+ if (cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET) == -1) {
+ fprintf(stderr, "Unable to set permitted capabilities: %s\n",
+ strerror(errno));
+ rc = EX_SYSERR;
+ goto free_caps;
+ }
+ if (parent) {
+ cap_list[0] = CAP_SYS_ADMIN;
+ if (cap_set_flag(caps, CAP_EFFECTIVE, 1, 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;
+}
+
+static int
+toggle_cap_dac_override(int enable)
+{
+ int rc;
+ cap_t caps;
+ cap_value_t cap_list;
+
+ if (getuid() != 0)
+ return 0;
+
+ 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;
+ }
+
+ cap_list = CAP_DAC_OVERRIDE;
+ if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_list,
+ enable ? CAP_SET : CAP_CLEAR) == -1) {
+ fprintf(stderr, "Unable to %s effective capabilities: %s\n",
+ enable ? "set" : "clear", strerror(errno));
+ rc = EX_SYSERR;
+ goto free_caps;
+ }
+free_caps:
+ cap_free(caps);
+ return 0;
+}
+#else /* HAVE_LIBCAP */
+static int
+drop_capabilities(int parent)
+{
+ return 0;
+}
+
+static int
+toggle_cap_dac_override(int enable)
+{
+ return 0;
+}
+#endif /* HAVE_LIBCAP */
+
static int open_cred_file(char *file_name,
struct parsed_mount_info *parsed_info)
{
char *line_buf;
char *temp_val, *newline;
- FILE *fs;
+ FILE *fs = NULL;
int i, length;
- i = access(file_name, R_OK);
+ i = toggle_cap_dac_override(1);
if (i)
return i;
+ i = access(file_name, R_OK);
+ if (i) {
+ toggle_cap_dac_override(0);
+ return i;
+ }
+
fs = fopen(file_name, "r");
- if (fs == NULL)
+ if (fs == NULL) {
+ toggle_cap_dac_override(0);
return errno;
+ }
+
+ i = toggle_cap_dac_override(0);
+ if (i) {
+ fclose(fs);
+ return i;
+ }
+
line_buf = (char *)malloc(4096);
if (line_buf == NULL) {
fclose(fs);
@@ -431,20 +552,33 @@ get_password_from_file(int file_descript, char *filename,
char buf[sizeof(parsed_info->password) + 1];
if (filename != NULL) {
+ rc = toggle_cap_dac_override(1);
+ if (rc)
+ return rc;
+
rc = access(filename, R_OK);
if (rc) {
fprintf(stderr,
"mount.cifs failed: access check of %s failed: %s\n",
filename, strerror(errno));
+ toggle_cap_dac_override(0);
return EX_SYSERR;
}
+
file_descript = open(filename, O_RDONLY);
if (file_descript < 0) {
fprintf(stderr,
"mount.cifs failed. %s attempting to open password file %s\n",
strerror(errno), filename);
+ toggle_cap_dac_override(0);
return EX_SYSERR;
}
+
+ rc = toggle_cap_dac_override(0);
+ if (rc) {
+ rc = EX_SYSERR;
+ goto get_pw_exit;
+ }
}
memset(buf, 0, sizeof(buf));
@@ -460,9 +594,8 @@ get_password_from_file(int file_descript, char *filename,
rc = set_password(parsed_info, buf);
get_pw_exit:
- if (filename != NULL) {
+ if (filename != NULL)
close(file_descript);
- }
return rc;
}
@@ -1073,7 +1206,7 @@ add_mtab(char *devname, char *mountpoint, unsigned long flags)
if (rc != 0) {
fprintf(stderr, "Unable to set real uid to effective uid: %s\n",
strerror(errno));
- rc = EX_FILEIO;
+ return EX_FILEIO;
}
rc = sigfillset(&mask);
@@ -1088,6 +1221,10 @@ add_mtab(char *devname, char *mountpoint, unsigned long flags)
return EX_FILEIO;
}
+ rc = toggle_cap_dac_override(1);
+ if (rc)
+ return EX_FILEIO;
+
atexit(unlock_mtab);
rc = lock_mtab();
if (rc) {
@@ -1137,6 +1274,7 @@ add_mtab(char *devname, char *mountpoint, unsigned long flags)
unlock_mtab();
SAFE_FREE(mountent.mnt_opts);
add_mtab_exit:
+ toggle_cap_dac_override(0);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
if (rc) {
fprintf(stderr, "unable to add mount entry to mtab\n");
@@ -1146,66 +1284,6 @@ add_mtab_exit:
return rc;
}
-#ifdef HAVE_LIBCAP
-static int
-drop_capabilities(int parent)
-{
- int rc = 0, ncap;
- 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;
- }
-
- if (parent || getuid() == 0) {
- ncap = 1;
- cap_list[0] = CAP_DAC_OVERRIDE;
- if (parent) {
- cap_list[1] = CAP_SYS_ADMIN;
- ++ncap;
- }
- if (cap_set_flag(caps, CAP_PERMITTED, ncap, 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, ncap, 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)