]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/nfsd/nfs4xdr.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[karo-tx-linux.git] / fs / nfsd / nfs4xdr.c
index 0dc11586682fd7d93c85790af67bd8d83f6f9002..8ca6d17f6cf3dc7505ce3e8754073fc9caa32a78 100644 (file)
@@ -293,13 +293,13 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                        ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
                        status = nfs_ok;
                        if (ace->whotype != NFS4_ACL_WHO_NAMED)
-                               ace->who = 0;
+                               ;
                        else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
                                status = nfsd_map_name_to_gid(argp->rqstp,
-                                               buf, dummy32, &ace->who);
+                                               buf, dummy32, &ace->who_gid);
                        else
                                status = nfsd_map_name_to_uid(argp->rqstp,
-                                               buf, dummy32, &ace->who);
+                                               buf, dummy32, &ace->who_uid);
                        if (status)
                                return status;
                }
@@ -464,9 +464,16 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
                        READ32(dummy);
                        READ_BUF(dummy * 4);
                        if (cbs->flavor == (u32)(-1)) {
-                               cbs->uid = uid;
-                               cbs->gid = gid;
-                               cbs->flavor = RPC_AUTH_UNIX;
+                               kuid_t kuid = make_kuid(&init_user_ns, uid);
+                               kgid_t kgid = make_kgid(&init_user_ns, gid);
+                               if (uid_valid(kuid) && gid_valid(kgid)) {
+                                       cbs->uid = kuid;
+                                       cbs->gid = kgid;
+                                       cbs->flavor = RPC_AUTH_UNIX;
+                               } else {
+                                       dprintk("RPC_AUTH_UNIX with invalid"
+                                               "uid or gid ignoring!\n");
+                               }
                        }
                        break;
                case RPC_AUTH_GSS:
@@ -1926,7 +1933,7 @@ static u32 nfs4_file_type(umode_t mode)
 }
 
 static __be32
-nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
+nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid,
                        __be32 **p, int *buflen)
 {
        int status;
@@ -1935,10 +1942,10 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
                return nfserr_resource;
        if (whotype != NFS4_ACL_WHO_NAMED)
                status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
-       else if (group)
-               status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
+       else if (gid_valid(gid))
+               status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1));
        else
-               status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
+               status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1));
        if (status < 0)
                return nfserrno(status);
        *p = xdr_encode_opaque(*p, NULL, status);
@@ -1948,22 +1955,33 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
 }
 
 static inline __be32
-nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
+nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen)
 {
-       return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
+       return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID,
+                                p, buflen);
 }
 
 static inline __be32
-nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
+nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen)
 {
-       return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
+       return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group,
+                                p, buflen);
 }
 
 static inline __be32
-nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
+nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
                __be32 **p, int *buflen)
 {
-       return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
+       kuid_t uid = INVALID_UID;
+       kgid_t gid = INVALID_GID;
+
+       if (ace->whotype == NFS4_ACL_WHO_NAMED) {
+               if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
+                       gid = ace->who_gid;
+               else
+                       uid = ace->who_uid;
+       }
+       return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen);
 }
 
 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
@@ -1997,7 +2015,7 @@ static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
                if (path.dentry != path.mnt->mnt_root)
                        break;
        }
-       err = vfs_getattr(path.mnt, path.dentry, stat);
+       err = vfs_getattr(&path, stat);
        path_put(&path);
        return err;
 }
@@ -2050,7 +2068,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                        goto out;
        }
 
-       err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
+       err = vfs_getattr(&path, &stat);
        if (err)
                goto out_nfserr;
        if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
@@ -2224,9 +2242,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                        WRITE32(ace->type);
                        WRITE32(ace->flag);
                        WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
-                       status = nfsd4_encode_aclname(rqstp, ace->whotype,
-                               ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,
-                               &p, &buflen);
+                       status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen);
                        if (status == nfserr_resource)
                                goto out_resource;
                        if (status)