nfs4acl.c (3554116d3aae25353713f3d0131d86ae6c1e5674) | nfs4acl.c (4ac7249ea5a0ceef9f8269f63f33cc873c3fac61) |
---|---|
1/* 2 * Common NFSv4 ACL handling code. 3 * 4 * Copyright (c) 2002, 2003 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Marius Aamodt Eriksen <marius@umich.edu> 8 * Jeff Sedlak <jsedlak@umich.edu> --- 23 unchanged lines hidden (view full) --- 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37#include <linux/slab.h> 38#include <linux/nfs_fs.h> 39#include <linux/export.h> | 1/* 2 * Common NFSv4 ACL handling code. 3 * 4 * Copyright (c) 2002, 2003 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Marius Aamodt Eriksen <marius@umich.edu> 8 * Jeff Sedlak <jsedlak@umich.edu> --- 23 unchanged lines hidden (view full) --- 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37#include <linux/slab.h> 38#include <linux/nfs_fs.h> 39#include <linux/export.h> |
40#include "nfsd.h" | 40#include "nfsfh.h" |
41#include "acl.h" | 41#include "acl.h" |
42#include "vfs.h" |
|
42 | 43 |
44#define NFS4_ACL_TYPE_DEFAULT 0x01 45#define NFS4_ACL_DIR 0x02 46#define NFS4_ACL_OWNER 0x04 |
|
43 44/* mode bit translations: */ 45#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) 46#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) 47#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE 48#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) 49#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) 50 --- 75 unchanged lines hidden (view full) --- 126 struct nfs4_ace *ace; 127 struct list_head ace_l; 128}; 129 130static short ace2type(struct nfs4_ace *); 131static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, 132 unsigned int); 133 | 47 48/* mode bit translations: */ 49#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) 50#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) 51#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE 52#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) 53#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) 54 --- 75 unchanged lines hidden (view full) --- 130 struct nfs4_ace *ace; 131 struct list_head ace_l; 132}; 133 134static short ace2type(struct nfs4_ace *); 135static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, 136 unsigned int); 137 |
134struct nfs4_acl * 135nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl, 136 unsigned int flags) | 138int 139nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, 140 struct nfs4_acl **acl) |
137{ | 141{ |
138 struct nfs4_acl *acl; | 142 struct inode *inode = dentry->d_inode; 143 int error = 0; 144 struct posix_acl *pacl = NULL, *dpacl = NULL; 145 unsigned int flags = 0; |
139 int size = 0; 140 | 146 int size = 0; 147 |
141 if (pacl) { 142 if (posix_acl_valid(pacl) < 0) 143 return ERR_PTR(-EINVAL); 144 size += 2*pacl->a_count; | 148 pacl = get_acl(inode, ACL_TYPE_ACCESS); 149 if (!pacl) { 150 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 151 if (IS_ERR(pacl)) 152 return PTR_ERR(pacl); 153 /* allocate for worst case: one (deny, allow) pair each: */ 154 size += 2 * pacl->a_count; |
145 } | 155 } |
146 if (dpacl) { 147 if (posix_acl_valid(dpacl) < 0) 148 return ERR_PTR(-EINVAL); 149 size += 2*dpacl->a_count; | 156 157 if (S_ISDIR(inode->i_mode)) { 158 flags = NFS4_ACL_DIR; 159 dpacl = get_acl(inode, ACL_TYPE_DEFAULT); 160 if (dpacl) 161 size += 2 * dpacl->a_count; 162 } else { 163 dpacl = NULL; |
150 } 151 | 164 } 165 |
152 /* Allocate for worst case: one (deny, allow) pair each: */ 153 acl = nfs4_acl_new(size); 154 if (acl == NULL) 155 return ERR_PTR(-ENOMEM); | 166 *acl = nfs4_acl_new(size); 167 if (*acl == NULL) { 168 error = -ENOMEM; 169 goto out; 170 } |
156 157 if (pacl) | 171 172 if (pacl) |
158 _posix_to_nfsv4_one(pacl, acl, flags & ~NFS4_ACL_TYPE_DEFAULT); | 173 _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); |
159 160 if (dpacl) | 174 175 if (dpacl) |
161 _posix_to_nfsv4_one(dpacl, acl, flags | NFS4_ACL_TYPE_DEFAULT); | 176 _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); |
162 | 177 |
163 return acl; | 178 out: 179 posix_acl_release(pacl); 180 posix_acl_release(dpacl); 181 return error; |
164} 165 166struct posix_acl_summary { 167 unsigned short owner; 168 unsigned short users; 169 unsigned short group; 170 unsigned short groups; 171 unsigned short other; --- 543 unchanged lines hidden (view full) --- 715 deny_bits(&state->other, mask); 716 deny_bits(&state->everyone, mask); 717 deny_bits_array(state->users, mask); 718 deny_bits_array(state->groups, mask); 719 } 720 } 721} 722 | 182} 183 184struct posix_acl_summary { 185 unsigned short owner; 186 unsigned short users; 187 unsigned short group; 188 unsigned short groups; 189 unsigned short other; --- 543 unchanged lines hidden (view full) --- 733 deny_bits(&state->other, mask); 734 deny_bits(&state->everyone, mask); 735 deny_bits_array(state->users, mask); 736 deny_bits_array(state->groups, mask); 737 } 738 } 739} 740 |
723int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, 724 struct posix_acl **dpacl, unsigned int flags) | 741static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, 742 struct posix_acl **pacl, struct posix_acl **dpacl, 743 unsigned int flags) |
725{ 726 struct posix_acl_state effective_acl_state, default_acl_state; 727 struct nfs4_ace *ace; 728 int ret; 729 730 ret = init_state(&effective_acl_state, acl->naces); 731 if (ret) 732 return ret; --- 43 unchanged lines hidden (view full) --- 776 ret = 0; 777out_dstate: 778 free_state(&default_acl_state); 779out_estate: 780 free_state(&effective_acl_state); 781 return ret; 782} 783 | 744{ 745 struct posix_acl_state effective_acl_state, default_acl_state; 746 struct nfs4_ace *ace; 747 int ret; 748 749 ret = init_state(&effective_acl_state, acl->naces); 750 if (ret) 751 return ret; --- 43 unchanged lines hidden (view full) --- 795 ret = 0; 796out_dstate: 797 free_state(&default_acl_state); 798out_estate: 799 free_state(&effective_acl_state); 800 return ret; 801} 802 |
803__be32 804nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, 805 struct nfs4_acl *acl) 806{ 807 __be32 error; 808 int host_error; 809 struct dentry *dentry; 810 struct inode *inode; 811 struct posix_acl *pacl = NULL, *dpacl = NULL; 812 unsigned int flags = 0; 813 814 /* Get inode */ 815 error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); 816 if (error) 817 return error; 818 819 dentry = fhp->fh_dentry; 820 inode = dentry->d_inode; 821 822 if (!inode->i_op->set_acl || !IS_POSIXACL(inode)) 823 return nfserr_attrnotsupp; 824 825 if (S_ISDIR(inode->i_mode)) 826 flags = NFS4_ACL_DIR; 827 828 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); 829 if (host_error == -EINVAL) 830 return nfserr_attrnotsupp; 831 if (host_error < 0) 832 goto out_nfserr; 833 834 host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS); 835 if (host_error < 0) 836 goto out_release; 837 838 if (S_ISDIR(inode->i_mode)) { 839 host_error = inode->i_op->set_acl(inode, dpacl, 840 ACL_TYPE_DEFAULT); 841 } 842 843out_release: 844 posix_acl_release(pacl); 845 posix_acl_release(dpacl); 846out_nfserr: 847 if (host_error == -EOPNOTSUPP) 848 return nfserr_attrnotsupp; 849 else 850 return nfserrno(host_error); 851} 852 853 |
|
784static short 785ace2type(struct nfs4_ace *ace) 786{ 787 switch (ace->whotype) { 788 case NFS4_ACL_WHO_NAMED: 789 return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? 790 ACL_GROUP : ACL_USER); 791 case NFS4_ACL_WHO_OWNER: 792 return ACL_USER_OBJ; 793 case NFS4_ACL_WHO_GROUP: 794 return ACL_GROUP_OBJ; 795 case NFS4_ACL_WHO_EVERYONE: 796 return ACL_OTHER; 797 } 798 BUG(); 799 return -1; 800} 801 | 854static short 855ace2type(struct nfs4_ace *ace) 856{ 857 switch (ace->whotype) { 858 case NFS4_ACL_WHO_NAMED: 859 return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? 860 ACL_GROUP : ACL_USER); 861 case NFS4_ACL_WHO_OWNER: 862 return ACL_USER_OBJ; 863 case NFS4_ACL_WHO_GROUP: 864 return ACL_GROUP_OBJ; 865 case NFS4_ACL_WHO_EVERYONE: 866 return ACL_OTHER; 867 } 868 BUG(); 869 return -1; 870} 871 |
802EXPORT_SYMBOL(nfs4_acl_posix_to_nfsv4); 803EXPORT_SYMBOL(nfs4_acl_nfsv4_to_posix); 804 | |
805struct nfs4_acl * 806nfs4_acl_new(int n) 807{ 808 struct nfs4_acl *acl; 809 810 acl = kmalloc(sizeof(*acl) + n*sizeof(struct nfs4_ace), GFP_KERNEL); 811 if (acl == NULL) 812 return NULL; --- 31 unchanged lines hidden (view full) --- 844 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 845 if (s2t_map[i].stringlen == len && 846 0 == memcmp(s2t_map[i].string, p, len)) 847 return s2t_map[i].type; 848 } 849 return NFS4_ACL_WHO_NAMED; 850} 851 | 872struct nfs4_acl * 873nfs4_acl_new(int n) 874{ 875 struct nfs4_acl *acl; 876 877 acl = kmalloc(sizeof(*acl) + n*sizeof(struct nfs4_ace), GFP_KERNEL); 878 if (acl == NULL) 879 return NULL; --- 31 unchanged lines hidden (view full) --- 911 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { 912 if (s2t_map[i].stringlen == len && 913 0 == memcmp(s2t_map[i].string, p, len)) 914 return s2t_map[i].type; 915 } 916 return NFS4_ACL_WHO_NAMED; 917} 918 |
852__be32 nfs4_acl_write_who(int who, __be32 **p, int *len) | 919int 920nfs4_acl_write_who(int who, char *p) |
853{ 854 int i; | 921{ 922 int i; |
855 int bytes; | |
856 857 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { | 923 924 for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { |
858 if (s2t_map[i].type != who) 859 continue; 860 bytes = 4 + (XDR_QUADLEN(s2t_map[i].stringlen) << 2); 861 if (bytes > *len) 862 return nfserr_resource; 863 *p = xdr_encode_opaque(*p, s2t_map[i].string, 864 s2t_map[i].stringlen); 865 *len -= bytes; 866 return 0; | 925 if (s2t_map[i].type == who) { 926 memcpy(p, s2t_map[i].string, s2t_map[i].stringlen); 927 return s2t_map[i].stringlen; 928 } |
867 } | 929 } |
868 WARN_ON_ONCE(1); | 930 BUG(); |
869 return -1; 870} | 931 return -1; 932} |
871 872EXPORT_SYMBOL(nfs4_acl_new); 873EXPORT_SYMBOL(nfs4_acl_get_whotype); 874EXPORT_SYMBOL(nfs4_acl_write_who); | |