Commit c207db2f authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

NFS: Convert NFSv2 to use the container user namespace

When mapping NFS identities, we want to substitute for the uids and
gids on the wire as we would for the AUTH_UNIX creds.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 58002399
...@@ -76,6 +76,20 @@ static int nfs_stat_to_errno(enum nfs_stat); ...@@ -76,6 +76,20 @@ static int nfs_stat_to_errno(enum nfs_stat);
* or decoded inline. * or decoded inline.
*/ */
static struct user_namespace *rpc_userns(const struct rpc_clnt *clnt)
{
if (clnt && clnt->cl_cred)
return clnt->cl_cred->user_ns;
return &init_user_ns;
}
static struct user_namespace *rpc_rqst_userns(const struct rpc_rqst *rqstp)
{
if (rqstp->rq_task)
return rpc_userns(rqstp->rq_task->tk_client);
return &init_user_ns;
}
/* /*
* typedef opaque nfsdata<>; * typedef opaque nfsdata<>;
*/ */
...@@ -248,7 +262,8 @@ static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep) ...@@ -248,7 +262,8 @@ static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
* }; * };
* *
*/ */
static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
struct user_namespace *userns)
{ {
u32 rdev, type; u32 rdev, type;
__be32 *p; __be32 *p;
...@@ -263,10 +278,10 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) ...@@ -263,10 +278,10 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
fattr->mode = be32_to_cpup(p++); fattr->mode = be32_to_cpup(p++);
fattr->nlink = be32_to_cpup(p++); fattr->nlink = be32_to_cpup(p++);
fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++)); fattr->uid = make_kuid(userns, be32_to_cpup(p++));
if (!uid_valid(fattr->uid)) if (!uid_valid(fattr->uid))
goto out_uid; goto out_uid;
fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++)); fattr->gid = make_kgid(userns, be32_to_cpup(p++));
if (!gid_valid(fattr->gid)) if (!gid_valid(fattr->gid))
goto out_gid; goto out_gid;
...@@ -321,7 +336,8 @@ static __be32 *xdr_time_not_set(__be32 *p) ...@@ -321,7 +336,8 @@ static __be32 *xdr_time_not_set(__be32 *p)
return p; return p;
} }
static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr) static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
struct user_namespace *userns)
{ {
struct timespec ts; struct timespec ts;
__be32 *p; __be32 *p;
...@@ -333,11 +349,11 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr) ...@@ -333,11 +349,11 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
else else
*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
if (attr->ia_valid & ATTR_UID) if (attr->ia_valid & ATTR_UID)
*p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid)); *p++ = cpu_to_be32(from_kuid_munged(userns, attr->ia_uid));
else else
*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
if (attr->ia_valid & ATTR_GID) if (attr->ia_valid & ATTR_GID)
*p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid)); *p++ = cpu_to_be32(from_kgid_munged(userns, attr->ia_gid));
else else
*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
if (attr->ia_valid & ATTR_SIZE) if (attr->ia_valid & ATTR_SIZE)
...@@ -451,7 +467,8 @@ static int decode_path(struct xdr_stream *xdr) ...@@ -451,7 +467,8 @@ static int decode_path(struct xdr_stream *xdr)
* }; * };
*/ */
static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result, static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
__u32 *op_status) __u32 *op_status,
struct user_namespace *userns)
{ {
enum nfs_stat status; enum nfs_stat status;
int error; int error;
...@@ -463,7 +480,7 @@ static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result, ...@@ -463,7 +480,7 @@ static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
*op_status = status; *op_status = status;
if (status != NFS_OK) if (status != NFS_OK)
goto out_default; goto out_default;
error = decode_fattr(xdr, result); error = decode_fattr(xdr, result, userns);
out: out:
return error; return error;
out_default: out_default:
...@@ -498,19 +515,21 @@ static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh, ...@@ -498,19 +515,21 @@ static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
* void; * void;
* }; * };
*/ */
static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result) static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result,
struct user_namespace *userns)
{ {
int error; int error;
error = decode_fhandle(xdr, result->fh); error = decode_fhandle(xdr, result->fh);
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
error = decode_fattr(xdr, result->fattr); error = decode_fattr(xdr, result->fattr, userns);
out: out:
return error; return error;
} }
static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result) static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result,
struct user_namespace *userns)
{ {
enum nfs_stat status; enum nfs_stat status;
int error; int error;
...@@ -520,7 +539,7 @@ static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result) ...@@ -520,7 +539,7 @@ static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
goto out; goto out;
if (status != NFS_OK) if (status != NFS_OK)
goto out_default; goto out_default;
error = decode_diropok(xdr, result); error = decode_diropok(xdr, result, userns);
out: out:
return error; return error;
out_default: out_default:
...@@ -559,7 +578,7 @@ static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, ...@@ -559,7 +578,7 @@ static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
const struct nfs_sattrargs *args = data; const struct nfs_sattrargs *args = data;
encode_fhandle(xdr, args->fh); encode_fhandle(xdr, args->fh);
encode_sattr(xdr, args->sattr); encode_sattr(xdr, args->sattr, rpc_rqst_userns(req));
} }
static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req, static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
...@@ -674,7 +693,7 @@ static void nfs2_xdr_enc_createargs(struct rpc_rqst *req, ...@@ -674,7 +693,7 @@ static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
const struct nfs_createargs *args = data; const struct nfs_createargs *args = data;
encode_diropargs(xdr, args->fh, args->name, args->len); encode_diropargs(xdr, args->fh, args->name, args->len);
encode_sattr(xdr, args->sattr); encode_sattr(xdr, args->sattr, rpc_rqst_userns(req));
} }
static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req, static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
...@@ -741,7 +760,7 @@ static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, ...@@ -741,7 +760,7 @@ static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen); encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
encode_path(xdr, args->pages, args->pathlen); encode_path(xdr, args->pages, args->pathlen);
encode_sattr(xdr, args->sattr); encode_sattr(xdr, args->sattr, rpc_rqst_userns(req));
} }
/* /*
...@@ -803,13 +822,13 @@ static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -803,13 +822,13 @@ static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr, static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
void *result) void *result)
{ {
return decode_attrstat(xdr, result, NULL); return decode_attrstat(xdr, result, NULL, rpc_rqst_userns(req));
} }
static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr, static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
void *result) void *result)
{ {
return decode_diropres(xdr, result); return decode_diropres(xdr, result, rpc_rqst_userns(req));
} }
/* /*
...@@ -864,7 +883,7 @@ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -864,7 +883,7 @@ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
result->op_status = status; result->op_status = status;
if (status != NFS_OK) if (status != NFS_OK)
goto out_default; goto out_default;
error = decode_fattr(xdr, result->fattr); error = decode_fattr(xdr, result->fattr, rpc_rqst_userns(req));
if (unlikely(error)) if (unlikely(error))
goto out; goto out;
error = decode_nfsdata(xdr, result); error = decode_nfsdata(xdr, result);
...@@ -881,7 +900,8 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr, ...@@ -881,7 +900,8 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
/* All NFSv2 writes are "file sync" writes */ /* All NFSv2 writes are "file sync" writes */
result->verf->committed = NFS_FILE_SYNC; result->verf->committed = NFS_FILE_SYNC;
return decode_attrstat(xdr, result->fattr, &result->op_status); return decode_attrstat(xdr, result->fattr, &result->op_status,
rpc_rqst_userns(req));
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment