diff options
Diffstat (limited to 'libmount/src/utils.c')
-rw-r--r-- | libmount/src/utils.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/libmount/src/utils.c b/libmount/src/utils.c index 711d1683e..5db5494d3 100644 --- a/libmount/src/utils.c +++ b/libmount/src/utils.c @@ -645,18 +645,37 @@ done: return rc; } -static int try_write(const char *filename) +static int try_write(const char *filename, const char *directory) { int rc = 0; if (!filename) return -EINVAL; + DBG(UTILS, ul_debug("try write %s dir: %s", filename, directory)); + #ifdef HAVE_EACCESS - if (eaccess(filename, R_OK|W_OK) != 0) - rc = -errno; -#else + /* Try eaccess() first, because open() is overkill, may be monitored by + * audit and we don't want to fill logs by our checks... + */ + if (eaccess(filename, R_OK|W_OK) == 0) { + DBG(UTILS, ul_debug(" access OK")); + return 0; + } else if (errno != ENOENT) { + DBG(UTILS, ul_debug(" access FAILED")); + return -errno; + } else if (directory) { + /* file does not exist; try if directory is writable */ + if (eaccess(directory, R_OK|W_OK) != 0) + rc = -errno; + + DBG(UTILS, ul_debug(" access %s [%s]", rc ? "FAILED" : "OK", directory)); + return rc; + } else +#endif { + DBG(UTILS, ul_debug(" doing open-write test")); + int fd = open(filename, O_RDWR|O_CREAT|O_CLOEXEC, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH); if (fd < 0) @@ -664,7 +683,6 @@ static int try_write(const char *filename) else close(fd); } -#endif return rc; } @@ -698,7 +716,7 @@ int mnt_has_regular_mtab(const char **mtab, int *writable) /* file exists */ if (S_ISREG(st.st_mode)) { if (writable) - *writable = !try_write(filename); + *writable = !try_write(filename, NULL); DBG(UTILS, ul_debug("%s: writable", filename)); return 1; } @@ -707,7 +725,7 @@ int mnt_has_regular_mtab(const char **mtab, int *writable) /* try to create the file */ if (writable) { - *writable = !try_write(filename); + *writable = !try_write(filename, NULL); if (*writable) { DBG(UTILS, ul_debug("%s: writable", filename)); return 1; @@ -747,7 +765,7 @@ int mnt_has_regular_utab(const char **utab, int *writable) /* file exists */ if (S_ISREG(st.st_mode)) { if (writable) - *writable = !try_write(filename); + *writable = !try_write(filename, NULL); return 1; } goto done; /* it's not a regular file */ @@ -764,11 +782,13 @@ int mnt_has_regular_utab(const char **utab, int *writable) rc = mkdir(dirname, S_IWUSR| S_IRUSR|S_IRGRP|S_IROTH| S_IXUSR|S_IXGRP|S_IXOTH); - free(dirname); - if (rc && errno != EEXIST) + if (rc && errno != EEXIST) { + free(dirname); goto done; /* probably EACCES */ + } - *writable = !try_write(filename); + *writable = !try_write(filename, dirname); + free(dirname); if (*writable) return 1; } |