This function checks if a given path is accessible under given uid and gid. --- src/util/util.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 3 ++ 2 files changed, 75 insertions(+), 0 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index af27344..f21e929 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -671,6 +671,66 @@ virFileIsExecutable(const char *file) } #ifndef WIN32 +/* Check that a file is accessible under certain + * user & gid. + * @mode can be F_OK, or a bitwise combination of R_OK, W_OK, and X_OK. + * see 'man access' for more details. + * Returns 0 on success, -1 on fail with errno set. + */ +int +virFileAccessibleAs(const char *path, int mode, + uid_t uid, gid_t gid) +{ + pid_t pid = 0; + int status, ret = 0; + int forkRet = 0; + + if (uid == getuid() && + gid == getgid()) + return access(path, mode); + + forkRet = virFork(&pid); + + if (pid < 0) { + return -1; + } + + if (pid) { /* parent */ + if (virPidWait(pid, &status) < 0) { + /* virPidWait() already + * reported error */ + return -1; + } + + return -(status & 0xFF); + } + + /* child. + * Return positive value here. Parent + * will change it to negative one. */ + + if (forkRet < 0) { + ret = 1; + goto childerror; + } + + if (virSetUIDGID(uid, gid) < 0) { + ret = 1; + goto childerror; + } + + if (access(path, mode) < 0) + ret = 1; + +childerror: + if ((ret & 0xFF) != ret) { + VIR_WARN("unable to pass desired return value %d", ret); + ret = 0xFF; + } + + _exit(ret); +} + /* return -errno on failure, or 0 on success */ static int virFileOpenAsNoFork(const char *path, int openflags, mode_t mode, @@ -993,6 +1053,18 @@ childerror: #else /* WIN32 */ +int +virFileAccessibleAs(const char *path, + int mode, + uid_t uid ATTRIBUTE_UNUSED, + git_t gid ATTRIBUTE_UNUSED) +{ + + VIR_WARN("Ignoring uid/gid due to WIN32"); + + return access(path, mode); +} + /* return -errno on failure, or 0 on success */ int virFileOpenAs(const char *path ATTRIBUTE_UNUSED, int openflags ATTRIBUTE_UNUSED, diff --git a/src/util/util.h b/src/util/util.h index c55e852..e869f1b 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -93,6 +93,9 @@ enum { VIR_FILE_OPEN_AS_UID = (1 << 0), VIR_FILE_OPEN_FORCE_PERMS = (1 << 1), }; +int virFileAccessibleAs(const char *path, int mode, + uid_t uid, gid_t gid) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virFileOpenAs(const char *path, int openflags, mode_t mode, uid_t uid, gid_t gid, unsigned int flags) -- 1.7.3.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list