summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2010-10-18 15:28:16 +0530
committerAnthony Liguori <aliguori@us.ibm.com>2010-10-20 12:10:58 -0500
commit70fc55ebe4fe5e72802468f16ae09169cf323b04 (patch)
tree8025ee78f471d7db195a3f546dd3ca2912695781
parentfc22118d9bb56ec71655b936a29513c140e6c289 (diff)
downloadqemu-70fc55ebe4fe5e72802468f16ae09169cf323b04.tar.gz
virtio-9p: Support mapped posix acl
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
-rw-r--r--Makefile.objs2
-rw-r--r--hw/virtio-9p-posix-acl.c140
-rw-r--r--hw/virtio-9p-xattr-user.c18
-rw-r--r--hw/virtio-9p-xattr.c4
-rw-r--r--hw/virtio-9p-xattr.h34
5 files changed, 192 insertions, 6 deletions
diff --git a/Makefile.objs b/Makefile.objs
index be4fade164..cd5a24b800 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -250,7 +250,7 @@ adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o virtio-9p-xattr.o
-hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o
+hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
######################################################################
# libdis
diff --git a/hw/virtio-9p-posix-acl.c b/hw/virtio-9p-posix-acl.c
new file mode 100644
index 0000000000..3978d0cf71
--- /dev/null
+++ b/hw/virtio-9p-posix-acl.c
@@ -0,0 +1,140 @@
+/*
+ * Virtio 9p system.posix* xattr callback
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <sys/types.h>
+#include <attr/xattr.h>
+#include "virtio.h"
+#include "virtio-9p.h"
+#include "file-op-9p.h"
+#include "virtio-9p-xattr.h"
+
+#define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
+#define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default"
+#define ACL_ACCESS "system.posix_acl_access"
+#define ACL_DEFAULT "system.posix_acl_default"
+
+static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
+ const char *name, void *value, size_t size)
+{
+ return lgetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size);
+}
+
+static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
+ char *name, void *value, size_t osize)
+{
+ ssize_t len = sizeof(ACL_ACCESS);
+
+ if (!value) {
+ return len;
+ }
+
+ if (osize < len) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ strncpy(value, ACL_ACCESS, len);
+ return 0;
+}
+
+static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
+ void *value, size_t size, int flags)
+{
+ return lsetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size, flags);
+}
+
+static int mp_pacl_removexattr(FsContext *ctx,
+ const char *path, const char *name)
+{
+ int ret;
+ ret = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS);
+ if (ret == -1 && errno == ENODATA) {
+ /*
+ * We don't get ENODATA error when trying to remote a
+ * posix acl that is not present. So don't throw the error
+ * even in case of mapped security model
+ */
+ errno = 0;
+ ret = 0;
+ }
+ return ret;
+}
+
+static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
+ const char *name, void *value, size_t size)
+{
+ return lgetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size);
+}
+
+static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
+ char *name, void *value, size_t osize)
+{
+ ssize_t len = sizeof(ACL_DEFAULT);
+
+ if (!value) {
+ return len;
+ }
+
+ if (osize < len) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ strncpy(value, ACL_DEFAULT, len);
+ return 0;
+}
+
+static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
+ void *value, size_t size, int flags)
+{
+ return lsetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size, flags);
+}
+
+static int mp_dacl_removexattr(FsContext *ctx,
+ const char *path, const char *name)
+{
+ return lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+}
+
+
+XattrOperations mapped_pacl_xattr = {
+ .name = "system.posix_acl_access",
+ .getxattr = mp_pacl_getxattr,
+ .setxattr = mp_pacl_setxattr,
+ .listxattr = mp_pacl_listxattr,
+ .removexattr = mp_pacl_removexattr,
+};
+
+XattrOperations mapped_dacl_xattr = {
+ .name = "system.posix_acl_default",
+ .getxattr = mp_dacl_getxattr,
+ .setxattr = mp_dacl_setxattr,
+ .listxattr = mp_dacl_listxattr,
+ .removexattr = mp_dacl_removexattr,
+};
+
+XattrOperations passthrough_acl_xattr = {
+ .name = "system.posix_acl_",
+ .getxattr = pt_getxattr,
+ .setxattr = pt_setxattr,
+ .listxattr = pt_listxattr,
+ .removexattr = pt_removexattr,
+};
+
+XattrOperations none_acl_xattr = {
+ .name = "system.posix_acl_",
+ .getxattr = notsup_getxattr,
+ .setxattr = notsup_setxattr,
+ .listxattr = notsup_listxattr,
+ .removexattr = notsup_removexattr,
+};
diff --git a/hw/virtio-9p-xattr-user.c b/hw/virtio-9p-xattr-user.c
index b14dbb9a61..faa02a1911 100644
--- a/hw/virtio-9p-xattr-user.c
+++ b/hw/virtio-9p-xattr-user.c
@@ -37,11 +37,19 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
{
int name_size = strlen(name) + 1;
if (strncmp(name, "user.virtfs.", 12) == 0) {
- /*
- * Don't allow fetch of user.virtfs namesapce
- * in case of mapped security
- */
- return 0;
+
+ /* check if it is a mapped posix acl */
+ if (strncmp(name, "user.virtfs.system.posix_acl_", 29) == 0) {
+ /* adjust the name and size */
+ name += 12;
+ name_size -= 12;
+ } else {
+ /*
+ * Don't allow fetch of user.virtfs namesapce
+ * in case of mapped security
+ */
+ return 0;
+ }
}
if (!value) {
return name_size;
diff --git a/hw/virtio-9p-xattr.c b/hw/virtio-9p-xattr.c
index 5ddc3c9fef..175f372c39 100644
--- a/hw/virtio-9p-xattr.c
+++ b/hw/virtio-9p-xattr.c
@@ -137,16 +137,20 @@ int v9fs_remove_xattr(FsContext *ctx,
XattrOperations *mapped_xattr_ops[] = {
&mapped_user_xattr,
+ &mapped_pacl_xattr,
+ &mapped_dacl_xattr,
NULL,
};
XattrOperations *passthrough_xattr_ops[] = {
&passthrough_user_xattr,
+ &passthrough_acl_xattr,
NULL,
};
/* for .user none model should be same as passthrough */
XattrOperations *none_xattr_ops[] = {
&passthrough_user_xattr,
+ &none_acl_xattr,
NULL,
};
diff --git a/hw/virtio-9p-xattr.h b/hw/virtio-9p-xattr.h
index 15632f8138..a6e31a152f 100644
--- a/hw/virtio-9p-xattr.h
+++ b/hw/virtio-9p-xattr.h
@@ -32,6 +32,11 @@ typedef struct xattr_operations
extern XattrOperations mapped_user_xattr;
extern XattrOperations passthrough_user_xattr;
+extern XattrOperations mapped_pacl_xattr;
+extern XattrOperations mapped_dacl_xattr;
+extern XattrOperations passthrough_acl_xattr;
+extern XattrOperations none_acl_xattr;
+
extern XattrOperations *mapped_xattr_ops[];
extern XattrOperations *passthrough_xattr_ops[];
extern XattrOperations *none_xattr_ops[];
@@ -66,4 +71,33 @@ static inline int pt_removexattr(FsContext *ctx,
return lremovexattr(rpath(ctx, path), name);
}
+static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,
+ const char *name, void *value,
+ size_t size)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+static inline int notsup_setxattr(FsContext *ctx, const char *path,
+ const char *name, void *value,
+ size_t size, int flags)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+static inline ssize_t notsup_listxattr(FsContext *ctx, const char *path,
+ char *name, void *value, size_t size)
+{
+ return 0;
+}
+
+static inline int notsup_removexattr(FsContext *ctx,
+ const char *path, const char *name)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
#endif