Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / nfsd / nfs4acl.c
index 1723939..edb107e 100644 (file)
 
 
 /* mode bit translations: */
-#define NFS4_READ_MODE (NFS4_ACE_READ_DATA | NFS4_ACE_READ_NAMED_ATTRS)
-#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_WRITE_NAMED_ATTRS | NFS4_ACE_APPEND_DATA)
+#define NFS4_READ_MODE (NFS4_ACE_READ_DATA)
+#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
 #define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
 #define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE)
 #define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
 
+/* We don't support these bits; insist they be neither allowed nor denied */
+#define NFS4_MASK_UNSUPP (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
+               | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
+
 /* flags used to simulate posix default ACLs */
 #define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
                | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
@@ -83,12 +87,15 @@ mask_from_posix(unsigned short perm, unsigned int flags)
 static u32
 deny_mask(u32 allow_mask, unsigned int flags)
 {
-       u32 ret = ~allow_mask & ~NFS4_ACE_DELETE;
+       u32 ret = ~allow_mask & ~NFS4_MASK_UNSUPP;
        if (!(flags & NFS4_ACL_DIR))
                ret &= ~NFS4_ACE_DELETE_CHILD;
        return ret;
 }
 
+/* XXX: modify functions to return NFS errors; they're only ever
+ * used by nfs code, after all.... */
+
 static int
 mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
 {
@@ -118,7 +125,7 @@ static short ace2type(struct nfs4_ace *);
 static int _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int);
 static struct posix_acl *_nfsv4_to_posix_one(struct nfs4_acl *, unsigned int);
 int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t);
-int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *);
+static int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *);
 
 struct nfs4_acl *
 nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl,
@@ -703,9 +710,9 @@ calculate_posix_ace_count(struct nfs4_acl *n4acl)
                /* Also, the remaining entries are for named users and
                 * groups, and come in threes (mask, allow, deny): */
                if (n4acl->naces < 7)
-                       return -1;
+                       return -EINVAL;
                if ((n4acl->naces - 7) % 3)
-                       return -1;
+                       return -EINVAL;
                return 4 + (n4acl->naces - 7)/3;
        }
 }
@@ -768,7 +775,7 @@ out_err:
        return pacl;
 }
 
-int
+static int
 nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
 {
        struct list_head *h, *n;
@@ -783,7 +790,7 @@ nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
                        continue;
 
                error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
-                               ace->access_mask, ace->whotype, ace->who) == -1;
+                               ace->access_mask, ace->whotype, ace->who);
                if (error < 0)
                        goto out;
 
@@ -859,7 +866,7 @@ nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask,
        struct nfs4_ace *ace;
 
        if ((ace = kmalloc(sizeof(*ace), GFP_KERNEL)) == NULL)
-               return -1;
+               return -ENOMEM;
 
        ace->type = type;
        ace->flag = flag;
@@ -900,7 +907,7 @@ nfs4_acl_get_whotype(char *p, u32 len)
 {
        int i;
 
-       for (i=0; i < sizeof(s2t_map) / sizeof(*s2t_map); i++) {
+       for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
                if (s2t_map[i].stringlen == len &&
                                0 == memcmp(s2t_map[i].string, p, len))
                        return s2t_map[i].type;
@@ -913,7 +920,7 @@ nfs4_acl_write_who(int who, char *p)
 {
        int i;
 
-       for (i=0; i < sizeof(s2t_map) / sizeof(*s2t_map); i++) {
+       for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
                if (s2t_map[i].type == who) {
                        memcpy(p, s2t_map[i].string, s2t_map[i].stringlen);
                        return s2t_map[i].stringlen;
@@ -940,35 +947,8 @@ match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
        }
 }
 
-/* 0 = granted, -EACCES = denied; mask is an nfsv4 mask, not mode bits */
-int
-nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group,
-                       uid_t who, u32 mask)
-{
-       struct nfs4_ace *ace;
-       u32 allowed = 0;
-
-       list_for_each_entry(ace, &acl->ace_head, l_ace) {
-               if (!match_who(ace, group, owner, who))
-                       continue;
-               switch (ace->type) {
-                       case NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE:
-                               allowed |= ace->access_mask;
-                               if ((allowed & mask) == mask)
-                                       return 0;
-                               break;
-                       case NFS4_ACE_ACCESS_DENIED_ACE_TYPE:
-                               if (ace->access_mask & mask)
-                                       return -EACCES;
-                               break;
-               }
-       }
-       return -EACCES;
-}
-
 EXPORT_SYMBOL(nfs4_acl_new);
 EXPORT_SYMBOL(nfs4_acl_free);
 EXPORT_SYMBOL(nfs4_acl_add_ace);
 EXPORT_SYMBOL(nfs4_acl_get_whotype);
 EXPORT_SYMBOL(nfs4_acl_write_who);
-EXPORT_SYMBOL(nfs4_acl_permission);