On Wed, Oct 19, 2011 at 04:42:57PM +0200, Michal Privoznik wrote:
This function checks if a given path is accessible under
given uid and gid.
---
src/util/util.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/util.h | 3 ++
2 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index dac616b..09d6281 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -671,6 +671,70 @@ virFileIsExecutable(const char *file)
}
#ifndef WIN32
+/* Check that a file is accessible under certain
+ * user & gid.
+ * @mode can be R_OK, W_OK, X_OK or F_OK.
+ * see 'man accesss' for more details.
+ * Returns 0 on success, -errno on fail,
+ * >0 on signaled child.
+ */
+int
+virFileAccessibleAs(const char *path, int mode,
+ uid_t uid, gid_t gid)
+{
+ pid_t pid;
+ int waitret, status, ret = 0;
+ int forkRet;
+
+ forkRet = virFork(&pid);
+
+ if (pid < 0) {
+ return -errno;
+ }
virFork() already raises a proper libvirt error on failure,
so returning 'errno' too is a little misleading / redundant.
Just return '-1' on error here & throughout the function
+
+ if (pid) { /* parent */
+ do {
+ if ((waitret = waitpid(pid, &status, 0)) < 0) {
+ ret = -errno;
+ virKillProcess(pid, SIGKILL);
+ return ret;
+ }
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+
+ /* child actually returns positive value
+ * anded by 0xFF (see man waitpid @ WEXITSTATUS)
+ */
+
+ if (WIFSIGNALED(status))
+ return WTERMSIG(status);
+
+ return -WEXITSTATUS(status);
+ }
+
+ /* child */
+
+ if (forkRet < 0) {
+ ret = errno;
+ goto childerror;
+ }
+
+ if (virSetUIDGID(uid, gid) < 0) {
+ ret = errno;
+ goto childerror;
+ }
+
+ if (access(path, mode) < 0)
+ ret = errno;
+
+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 +1057,18 @@ childerror:
#else /* WIN32 */
+int
+virFileAccessibleAs(const char *path ATTRIBUTE_UNUSED,
+ int mode ATTRIBUTE_UNUSED,
+ uid_t uid ATTRIBUTE_UNUSED,
+ git_t gid ATTRIBUTE_UNUSED)
+{
+ virUtilError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("virFileAccessibleAs is not implemented for
WIN32"));
+
+ return -ENOSYS;
+}
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|