aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-15 14:11:45 -0400
committerSage Weil <sage@inktank.com>2013-08-15 14:11:45 -0400
commitee3e542fec6e69bc9fb668698889a37d93950ddf (patch)
treee74ee766a4764769ef1d3d45d266b4dea64101d3 /fs/nfsd/nfs4proc.c
parentfe2a801b50c0bb8039d627e5ae1fec249d10ff39 (diff)
parentf1d6e17f540af37bb1891480143669ba7636c4cf (diff)
Merge remote-tracking branch 'linus/master' into testing
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r--fs/nfsd/nfs4proc.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 27d74a294515..419572f33b72 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -42,6 +42,36 @@
42#include "current_stateid.h" 42#include "current_stateid.h"
43#include "netns.h" 43#include "netns.h"
44 44
45#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
46#include <linux/security.h>
47
48static inline void
49nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
50{
51 struct inode *inode = resfh->fh_dentry->d_inode;
52 int status;
53
54 mutex_lock(&inode->i_mutex);
55 status = security_inode_setsecctx(resfh->fh_dentry,
56 label->data, label->len);
57 mutex_unlock(&inode->i_mutex);
58
59 if (status)
60 /*
61 * XXX: We should really fail the whole open, but we may
62 * already have created a new file, so it may be too
63 * late. For now this seems the least of evils:
64 */
65 bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
66
67 return;
68}
69#else
70static inline void
71nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
72{ }
73#endif
74
45#define NFSDDBG_FACILITY NFSDDBG_PROC 75#define NFSDDBG_FACILITY NFSDDBG_PROC
46 76
47static u32 nfsd_attrmask[] = { 77static u32 nfsd_attrmask[] = {
@@ -239,6 +269,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
239 (u32 *)open->op_verf.data, 269 (u32 *)open->op_verf.data,
240 &open->op_truncate, &open->op_created); 270 &open->op_truncate, &open->op_created);
241 271
272 if (!status && open->op_label.len)
273 nfsd4_security_inode_setsecctx(resfh, &open->op_label, open->op_bmval);
274
242 /* 275 /*
243 * Following rfc 3530 14.2.16, use the returned bitmask 276 * Following rfc 3530 14.2.16, use the returned bitmask
244 * to indicate which attributes we used to store the 277 * to indicate which attributes we used to store the
@@ -263,7 +296,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
263 296
264 nfsd4_set_open_owner_reply_cache(cstate, open, resfh); 297 nfsd4_set_open_owner_reply_cache(cstate, open, resfh);
265 accmode = NFSD_MAY_NOP; 298 accmode = NFSD_MAY_NOP;
266 if (open->op_created) 299 if (open->op_created ||
300 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
267 accmode |= NFSD_MAY_OWNER_OVERRIDE; 301 accmode |= NFSD_MAY_OWNER_OVERRIDE;
268 status = do_open_permission(rqstp, resfh, open, accmode); 302 status = do_open_permission(rqstp, resfh, open, accmode);
269 set_change_info(&open->op_cinfo, current_fh); 303 set_change_info(&open->op_cinfo, current_fh);
@@ -637,6 +671,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
637 if (status) 671 if (status)
638 goto out; 672 goto out;
639 673
674 if (create->cr_label.len)
675 nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval);
676
640 if (create->cr_acl != NULL) 677 if (create->cr_acl != NULL)
641 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, 678 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
642 create->cr_bmval); 679 create->cr_bmval);
@@ -916,6 +953,11 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
916 setattr->sa_acl); 953 setattr->sa_acl);
917 if (status) 954 if (status)
918 goto out; 955 goto out;
956 if (setattr->sa_label.len)
957 status = nfsd4_set_nfs4_label(rqstp, &cstate->current_fh,
958 &setattr->sa_label);
959 if (status)
960 goto out;
919 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 961 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
920 0, (time_t)0); 962 0, (time_t)0);
921out: 963out:
@@ -1251,7 +1293,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1251 * According to RFC3010, this takes precedence over all other errors. 1293 * According to RFC3010, this takes precedence over all other errors.
1252 */ 1294 */
1253 status = nfserr_minor_vers_mismatch; 1295 status = nfserr_minor_vers_mismatch;
1254 if (args->minorversion > nfsd_supported_minorversion) 1296 if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
1255 goto out; 1297 goto out;
1256 1298
1257 status = nfs41_check_op_ordering(args); 1299 status = nfs41_check_op_ordering(args);
@@ -1482,7 +1524,7 @@ static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1482static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1524static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1483{ 1525{
1484 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ 1526 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
1485 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\ 1527 1 + 1 + 2 + /* eir_flags, spr_how, spo_must_enforce & _allow */\
1486 2 + /*eir_server_owner.so_minor_id */\ 1528 2 + /*eir_server_owner.so_minor_id */\
1487 /* eir_server_owner.so_major_id<> */\ 1529 /* eir_server_owner.so_major_id<> */\
1488 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1530 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\