diff options
Diffstat (limited to 'fs/nfsd/nfs4acl.c')
| -rw-r--r-- | fs/nfsd/nfs4acl.c | 63 | 
1 files changed, 46 insertions, 17 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 9c51aff02ae..8a50b3c1809 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -264,7 +264,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,  			ace->flag = eflag;  			ace->access_mask = deny_mask_from_posix(deny, flags);  			ace->whotype = NFS4_ACL_WHO_NAMED; -			ace->who = pa->e_id; +			ace->who_uid = pa->e_uid;  			ace++;  			acl->naces++;  		} @@ -273,7 +273,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,  		ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,  						   flags);  		ace->whotype = NFS4_ACL_WHO_NAMED; -		ace->who = pa->e_id; +		ace->who_uid = pa->e_uid;  		ace++;  		acl->naces++;  		pa++; @@ -300,7 +300,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,  		ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,  						   flags);  		ace->whotype = NFS4_ACL_WHO_NAMED; -		ace->who = pa->e_id; +		ace->who_gid = pa->e_gid;  		ace++;  		acl->naces++;  		pa++; @@ -329,7 +329,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,  			ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;  			ace->access_mask = deny_mask_from_posix(deny, flags);  			ace->whotype = NFS4_ACL_WHO_NAMED; -			ace->who = pa->e_id; +			ace->who_gid = pa->e_gid;  			ace++;  			acl->naces++;  		} @@ -345,6 +345,18 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,  	acl->naces++;  } +static bool +pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2) +{ +	if (pace1->e_tag != pace2->e_tag) +		return pace1->e_tag > pace2->e_tag; +	if (pace1->e_tag == ACL_USER) +		return uid_gt(pace1->e_uid, pace2->e_uid); +	if (pace1->e_tag == ACL_GROUP) +		return gid_gt(pace1->e_gid, pace2->e_gid); +	return false; +} +  static void  sort_pacl_range(struct posix_acl *pacl, int start, int end) {  	int sorted = 0, i; @@ -355,8 +367,8 @@ sort_pacl_range(struct posix_acl *pacl, int start, int end) {  	while (!sorted) {  		sorted = 1;  		for (i = start; i < end; i++) { -			if (pacl->a_entries[i].e_id -					> pacl->a_entries[i+1].e_id) { +			if (pace_gt(&pacl->a_entries[i], +				    &pacl->a_entries[i+1])) {  				sorted = 0;  				tmp = pacl->a_entries[i];  				pacl->a_entries[i] = pacl->a_entries[i+1]; @@ -398,7 +410,10 @@ struct posix_ace_state {  };  struct posix_user_ace_state { -	uid_t uid; +	union { +		kuid_t uid; +		kgid_t gid; +	};  	struct posix_ace_state perms;  }; @@ -521,7 +536,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)  	if (error)  		goto out_err;  	low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); -	pace->e_id = ACL_UNDEFINED_ID;  	for (i=0; i < state->users->n; i++) {  		pace++; @@ -531,7 +545,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)  			goto out_err;  		low_mode_from_nfs4(state->users->aces[i].perms.allow,  					&pace->e_perm, flags); -		pace->e_id = state->users->aces[i].uid; +		pace->e_uid = state->users->aces[i].uid;  		add_to_mask(state, &state->users->aces[i].perms);  	} @@ -541,7 +555,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)  	if (error)  		goto out_err;  	low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); -	pace->e_id = ACL_UNDEFINED_ID;  	add_to_mask(state, &state->group);  	for (i=0; i < state->groups->n; i++) { @@ -552,14 +565,13 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)  			goto out_err;  		low_mode_from_nfs4(state->groups->aces[i].perms.allow,  					&pace->e_perm, flags); -		pace->e_id = state->groups->aces[i].uid; +		pace->e_gid = state->groups->aces[i].gid;  		add_to_mask(state, &state->groups->aces[i].perms);  	}  	pace++;  	pace->e_tag = ACL_MASK;  	low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags); -	pace->e_id = ACL_UNDEFINED_ID;  	pace++;  	pace->e_tag = ACL_OTHER; @@ -567,7 +579,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)  	if (error)  		goto out_err;  	low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); -	pace->e_id = ACL_UNDEFINED_ID;  	return pacl;  out_err: @@ -587,12 +598,13 @@ static inline void deny_bits(struct posix_ace_state *astate, u32 mask)  	astate->deny |= mask & ~astate->allow;  } -static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid) +static int find_uid(struct posix_acl_state *state, kuid_t uid)  { +	struct posix_ace_state_array *a = state->users;  	int i;  	for (i = 0; i < a->n; i++) -		if (a->aces[i].uid == uid) +		if (uid_eq(a->aces[i].uid, uid))  			return i;  	/* Not found: */  	a->n++; @@ -603,6 +615,23 @@ static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array  	return i;  } +static int find_gid(struct posix_acl_state *state, kgid_t gid) +{ +	struct posix_ace_state_array *a = state->groups; +	int i; + +	for (i = 0; i < a->n; i++) +		if (gid_eq(a->aces[i].gid, gid)) +			return i; +	/* Not found: */ +	a->n++; +	a->aces[i].gid = gid; +	a->aces[i].perms.allow = state->everyone.allow; +	a->aces[i].perms.deny  = state->everyone.deny; + +	return i; +} +  static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)  {  	int i; @@ -636,7 +665,7 @@ static void process_one_v4_ace(struct posix_acl_state *state,  		}  		break;  	case ACL_USER: -		i = find_uid(state, state->users, ace->who); +		i = find_uid(state, ace->who_uid);  		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {  			allow_bits(&state->users->aces[i].perms, mask);  		} else { @@ -658,7 +687,7 @@ static void process_one_v4_ace(struct posix_acl_state *state,  		}  		break;  	case ACL_GROUP: -		i = find_uid(state, state->groups, ace->who); +		i = find_gid(state, ace->who_gid);  		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {  			allow_bits(&state->groups->aces[i].perms, mask);  		} else {  |