@@ -245,7 +245,8 @@ sound-obj-$(CONFIG_CS4231A) += cs4231a.o
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 virtio-9p-xattr-user.o
+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 virtio-9p-posix-acl.o
######################################################################
# libdis
new file mode 100644
@@ -0,0 +1,144 @@
+/*
+ * 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,
+ void *value, size_t osize)
+{
+ ssize_t size;
+ ssize_t len = sizeof(ACL_ACCESS);
+
+ size = mp_pacl_getxattr(ctx, path, MAP_ACL_ACCESS, NULL, 0);
+ if (size > 0) {
+ if (!value) {
+ return len;
+ }
+ if (osize >= len) {
+ strncpy(value, ACL_ACCESS, len);
+ } else {
+ errno = ERANGE;
+ return -1;
+ }
+ }
+ 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,
+ void *value, size_t osize)
+{
+ ssize_t size;
+ ssize_t len = sizeof(ACL_DEFAULT);
+
+ size = mp_dacl_getxattr(ctx, path, MAP_ACL_DEFAULT, NULL, 0);
+ if (size > 0) {
+ if (!value) {
+ return len;
+ }
+ if (osize >= len) {
+ strncpy(value, ACL_DEFAULT, len);
+ } else {
+ errno = ERANGE;
+ return -1;
+ }
+ }
+ 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,
+ .removexattr = pt_removexattr,
+};
+
+XattrOperations none_acl_xattr = {
+ .name = "system.posix_acl_",
+ .getxattr = notsup_getxattr,
+ .setxattr = notsup_setxattr,
+ .removexattr = notsup_removexattr,
+};
@@ -96,16 +96,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,
};
@@ -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[];
@@ -64,4 +69,27 @@ 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 int notsup_removexattr(FsContext *ctx,
+ const char *path, const char *name)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
#endif
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- Makefile.objs | 3 +- hw/virtio-9p-posix-acl.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ hw/virtio-9p-xattr.c | 4 + hw/virtio-9p-xattr.h | 28 +++++++++ 4 files changed, 178 insertions(+), 1 deletions(-) create mode 100644 hw/virtio-9p-posix-acl.c