qemu/hw/9pfs/9p-posix-acl.c
<<
>>
Prefs
   1/*
   2 * 9p system.posix* xattr callback
   3 *
   4 * Copyright IBM, Corp. 2010
   5 *
   6 * Authors:
   7 * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 */
  13
  14#include "qemu/osdep.h"
  15#include "qemu/xattr.h"
  16#include "9p.h"
  17#include "fsdev/file-op-9p.h"
  18#include "9p-xattr.h"
  19
  20#define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
  21#define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default"
  22#define ACL_ACCESS "system.posix_acl_access"
  23#define ACL_DEFAULT "system.posix_acl_default"
  24
  25static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
  26                                const char *name, void *value, size_t size)
  27{
  28    char *buffer;
  29    ssize_t ret;
  30
  31    buffer = rpath(ctx, path);
  32    ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size);
  33    g_free(buffer);
  34    return ret;
  35}
  36
  37static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
  38                                 char *name, void *value, size_t osize)
  39{
  40    ssize_t len = sizeof(ACL_ACCESS);
  41
  42    if (!value) {
  43        return len;
  44    }
  45
  46    if (osize < len) {
  47        errno = ERANGE;
  48        return -1;
  49    }
  50
  51    /* len includes the trailing NUL */
  52    memcpy(value, ACL_ACCESS, len);
  53    return 0;
  54}
  55
  56static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
  57                            void *value, size_t size, int flags)
  58{
  59    char *buffer;
  60    int ret;
  61
  62    buffer = rpath(ctx, path);
  63    ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags);
  64    g_free(buffer);
  65    return ret;
  66}
  67
  68static int mp_pacl_removexattr(FsContext *ctx,
  69                               const char *path, const char *name)
  70{
  71    int ret;
  72    char *buffer;
  73
  74    buffer = rpath(ctx, path);
  75    ret  = lremovexattr(buffer, MAP_ACL_ACCESS);
  76    if (ret == -1 && errno == ENODATA) {
  77        /*
  78         * We don't get ENODATA error when trying to remove a
  79         * posix acl that is not present. So don't throw the error
  80         * even in case of mapped security model
  81         */
  82        errno = 0;
  83        ret = 0;
  84    }
  85    g_free(buffer);
  86    return ret;
  87}
  88
  89static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
  90                                const char *name, void *value, size_t size)
  91{
  92    char *buffer;
  93    ssize_t ret;
  94
  95    buffer = rpath(ctx, path);
  96    ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size);
  97    g_free(buffer);
  98    return ret;
  99}
 100
 101static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
 102                                 char *name, void *value, size_t osize)
 103{
 104    ssize_t len = sizeof(ACL_DEFAULT);
 105
 106    if (!value) {
 107        return len;
 108    }
 109
 110    if (osize < len) {
 111        errno = ERANGE;
 112        return -1;
 113    }
 114
 115    /* len includes the trailing NUL */
 116    memcpy(value, ACL_DEFAULT, len);
 117    return 0;
 118}
 119
 120static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
 121                            void *value, size_t size, int flags)
 122{
 123    char *buffer;
 124    int ret;
 125
 126    buffer = rpath(ctx, path);
 127    ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags);
 128    g_free(buffer);
 129    return ret;
 130}
 131
 132static int mp_dacl_removexattr(FsContext *ctx,
 133                               const char *path, const char *name)
 134{
 135    int ret;
 136    char *buffer;
 137
 138    buffer = rpath(ctx, path);
 139    ret  = lremovexattr(buffer, MAP_ACL_DEFAULT);
 140    if (ret == -1 && errno == ENODATA) {
 141        /*
 142         * We don't get ENODATA error when trying to remove a
 143         * posix acl that is not present. So don't throw the error
 144         * even in case of mapped security model
 145         */
 146        errno = 0;
 147        ret = 0;
 148    }
 149    g_free(buffer);
 150    return ret;
 151}
 152
 153
 154XattrOperations mapped_pacl_xattr = {
 155    .name = "system.posix_acl_access",
 156    .getxattr = mp_pacl_getxattr,
 157    .setxattr = mp_pacl_setxattr,
 158    .listxattr = mp_pacl_listxattr,
 159    .removexattr = mp_pacl_removexattr,
 160};
 161
 162XattrOperations mapped_dacl_xattr = {
 163    .name = "system.posix_acl_default",
 164    .getxattr = mp_dacl_getxattr,
 165    .setxattr = mp_dacl_setxattr,
 166    .listxattr = mp_dacl_listxattr,
 167    .removexattr = mp_dacl_removexattr,
 168};
 169
 170XattrOperations passthrough_acl_xattr = {
 171    .name = "system.posix_acl_",
 172    .getxattr = pt_getxattr,
 173    .setxattr = pt_setxattr,
 174    .listxattr = pt_listxattr,
 175    .removexattr = pt_removexattr,
 176};
 177
 178XattrOperations none_acl_xattr = {
 179    .name = "system.posix_acl_",
 180    .getxattr = notsup_getxattr,
 181    .setxattr = notsup_setxattr,
 182    .listxattr = notsup_listxattr,
 183    .removexattr = notsup_removexattr,
 184};
 185