aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c145
1 files changed, 100 insertions, 45 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1a468bbd330f..990181103214 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -44,13 +44,14 @@
44#include <linux/namei.h> 44#include <linux/namei.h>
45#include <linux/statfs.h> 45#include <linux/statfs.h>
46#include <linux/utsname.h> 46#include <linux/utsname.h>
47#include <linux/nfsd_idmap.h>
48#include <linux/nfs4_acl.h>
49#include <linux/sunrpc/svcauth_gss.h> 47#include <linux/sunrpc/svcauth_gss.h>
50 48
49#include "idmap.h"
50#include "acl.h"
51#include "xdr4.h" 51#include "xdr4.h"
52#include "vfs.h" 52#include "vfs.h"
53 53
54
54#define NFSDDBG_FACILITY NFSDDBG_XDR 55#define NFSDDBG_FACILITY NFSDDBG_XDR
55 56
56/* 57/*
@@ -288,17 +289,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
288 len += XDR_QUADLEN(dummy32) << 2; 289 len += XDR_QUADLEN(dummy32) << 2;
289 READMEM(buf, dummy32); 290 READMEM(buf, dummy32);
290 ace->whotype = nfs4_acl_get_whotype(buf, dummy32); 291 ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
291 host_err = 0; 292 status = nfs_ok;
292 if (ace->whotype != NFS4_ACL_WHO_NAMED) 293 if (ace->whotype != NFS4_ACL_WHO_NAMED)
293 ace->who = 0; 294 ace->who = 0;
294 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 295 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
295 host_err = nfsd_map_name_to_gid(argp->rqstp, 296 status = nfsd_map_name_to_gid(argp->rqstp,
296 buf, dummy32, &ace->who); 297 buf, dummy32, &ace->who);
297 else 298 else
298 host_err = nfsd_map_name_to_uid(argp->rqstp, 299 status = nfsd_map_name_to_uid(argp->rqstp,
299 buf, dummy32, &ace->who); 300 buf, dummy32, &ace->who);
300 if (host_err) 301 if (status)
301 goto out_nfserr; 302 return status;
302 } 303 }
303 } else 304 } else
304 *acl = NULL; 305 *acl = NULL;
@@ -316,8 +317,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
316 READ_BUF(dummy32); 317 READ_BUF(dummy32);
317 len += (XDR_QUADLEN(dummy32) << 2); 318 len += (XDR_QUADLEN(dummy32) << 2);
318 READMEM(buf, dummy32); 319 READMEM(buf, dummy32);
319 if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) 320 if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
320 goto out_nfserr; 321 return status;
321 iattr->ia_valid |= ATTR_UID; 322 iattr->ia_valid |= ATTR_UID;
322 } 323 }
323 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { 324 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
@@ -327,8 +328,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
327 READ_BUF(dummy32); 328 READ_BUF(dummy32);
328 len += (XDR_QUADLEN(dummy32) << 2); 329 len += (XDR_QUADLEN(dummy32) << 2);
329 READMEM(buf, dummy32); 330 READMEM(buf, dummy32);
330 if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) 331 if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
331 goto out_nfserr; 332 return status;
332 iattr->ia_valid |= ATTR_GID; 333 iattr->ia_valid |= ATTR_GID;
333 } 334 }
334 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { 335 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
@@ -420,6 +421,18 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
420 DECODE_TAIL; 421 DECODE_TAIL;
421} 422}
422 423
424static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
425{
426 DECODE_HEAD;
427
428 READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
429 COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
430 READ32(bcts->dir);
431 /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker
432 * could help us figure out we should be using it. */
433 DECODE_TAIL;
434}
435
423static __be32 436static __be32
424nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) 437nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
425{ 438{
@@ -572,8 +585,6 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
572 READ_BUF(lockt->lt_owner.len); 585 READ_BUF(lockt->lt_owner.len);
573 READMEM(lockt->lt_owner.data, lockt->lt_owner.len); 586 READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
574 587
575 if (argp->minorversion && !zero_clientid(&lockt->lt_clientid))
576 return nfserr_inval;
577 DECODE_TAIL; 588 DECODE_TAIL;
578} 589}
579 590
@@ -847,6 +858,17 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
847} 858}
848 859
849static __be32 860static __be32
861nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
862 struct nfsd4_secinfo_no_name *sin)
863{
864 DECODE_HEAD;
865
866 READ_BUF(4);
867 READ32(sin->sin_style);
868 DECODE_TAIL;
869}
870
871static __be32
850nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 872nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
851{ 873{
852 __be32 status; 874 __be32 status;
@@ -1005,7 +1027,7 @@ static __be32
1005nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, 1027nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1006 struct nfsd4_exchange_id *exid) 1028 struct nfsd4_exchange_id *exid)
1007{ 1029{
1008 int dummy; 1030 int dummy, tmp;
1009 DECODE_HEAD; 1031 DECODE_HEAD;
1010 1032
1011 READ_BUF(NFS4_VERIFIER_SIZE); 1033 READ_BUF(NFS4_VERIFIER_SIZE);
@@ -1053,15 +1075,23 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1053 1075
1054 /* ssp_hash_algs<> */ 1076 /* ssp_hash_algs<> */
1055 READ_BUF(4); 1077 READ_BUF(4);
1056 READ32(dummy); 1078 READ32(tmp);
1057 READ_BUF(dummy); 1079 while (tmp--) {
1058 p += XDR_QUADLEN(dummy); 1080 READ_BUF(4);
1081 READ32(dummy);
1082 READ_BUF(dummy);
1083 p += XDR_QUADLEN(dummy);
1084 }
1059 1085
1060 /* ssp_encr_algs<> */ 1086 /* ssp_encr_algs<> */
1061 READ_BUF(4); 1087 READ_BUF(4);
1062 READ32(dummy); 1088 READ32(tmp);
1063 READ_BUF(dummy); 1089 while (tmp--) {
1064 p += XDR_QUADLEN(dummy); 1090 READ_BUF(4);
1091 READ32(dummy);
1092 READ_BUF(dummy);
1093 p += XDR_QUADLEN(dummy);
1094 }
1065 1095
1066 /* ssp_window and ssp_num_gss_handles */ 1096 /* ssp_window and ssp_num_gss_handles */
1067 READ_BUF(8); 1097 READ_BUF(8);
@@ -1180,8 +1210,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1180 READ_BUF(4); 1210 READ_BUF(4);
1181 READ32(dummy); 1211 READ32(dummy);
1182 READ_BUF(dummy * 4); 1212 READ_BUF(dummy * 4);
1183 for (i = 0; i < dummy; ++i)
1184 READ32(dummy);
1185 break; 1213 break;
1186 case RPC_AUTH_GSS: 1214 case RPC_AUTH_GSS:
1187 dprintk("RPC_AUTH_GSS callback secflavor " 1215 dprintk("RPC_AUTH_GSS callback secflavor "
@@ -1197,7 +1225,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1197 READ_BUF(4); 1225 READ_BUF(4);
1198 READ32(dummy); 1226 READ32(dummy);
1199 READ_BUF(dummy); 1227 READ_BUF(dummy);
1200 p += XDR_QUADLEN(dummy);
1201 break; 1228 break;
1202 default: 1229 default:
1203 dprintk("Illegal callback secflavor\n"); 1230 dprintk("Illegal callback secflavor\n");
@@ -1339,7 +1366,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1339 1366
1340 /* new operations for NFSv4.1 */ 1367 /* new operations for NFSv4.1 */
1341 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp, 1368 [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_notsupp,
1342 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_notsupp, 1369 [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1343 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id, 1370 [OP_EXCHANGE_ID] = (nfsd4_dec)nfsd4_decode_exchange_id,
1344 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session, 1371 [OP_CREATE_SESSION] = (nfsd4_dec)nfsd4_decode_create_session,
1345 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session, 1372 [OP_DESTROY_SESSION] = (nfsd4_dec)nfsd4_decode_destroy_session,
@@ -1350,7 +1377,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
1350 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, 1377 [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp,
1351 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, 1378 [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp,
1352 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, 1379 [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp,
1353 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_notsupp, 1380 [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1354 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, 1381 [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence,
1355 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, 1382 [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp,
1356 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, 1383 [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -1805,19 +1832,23 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1805 goto out_nfserr; 1832 goto out_nfserr;
1806 } 1833 }
1807 } 1834 }
1808 if ((buflen -= 16) < 0)
1809 goto out_resource;
1810 1835
1811 if (unlikely(bmval2)) { 1836 if (bmval2) {
1837 if ((buflen -= 16) < 0)
1838 goto out_resource;
1812 WRITE32(3); 1839 WRITE32(3);
1813 WRITE32(bmval0); 1840 WRITE32(bmval0);
1814 WRITE32(bmval1); 1841 WRITE32(bmval1);
1815 WRITE32(bmval2); 1842 WRITE32(bmval2);
1816 } else if (likely(bmval1)) { 1843 } else if (bmval1) {
1844 if ((buflen -= 12) < 0)
1845 goto out_resource;
1817 WRITE32(2); 1846 WRITE32(2);
1818 WRITE32(bmval0); 1847 WRITE32(bmval0);
1819 WRITE32(bmval1); 1848 WRITE32(bmval1);
1820 } else { 1849 } else {
1850 if ((buflen -= 8) < 0)
1851 goto out_resource;
1821 WRITE32(1); 1852 WRITE32(1);
1822 WRITE32(bmval0); 1853 WRITE32(bmval0);
1823 } 1854 }
@@ -1828,15 +1859,17 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1828 u32 word1 = nfsd_suppattrs1(minorversion); 1859 u32 word1 = nfsd_suppattrs1(minorversion);
1829 u32 word2 = nfsd_suppattrs2(minorversion); 1860 u32 word2 = nfsd_suppattrs2(minorversion);
1830 1861
1831 if ((buflen -= 12) < 0)
1832 goto out_resource;
1833 if (!aclsupport) 1862 if (!aclsupport)
1834 word0 &= ~FATTR4_WORD0_ACL; 1863 word0 &= ~FATTR4_WORD0_ACL;
1835 if (!word2) { 1864 if (!word2) {
1865 if ((buflen -= 12) < 0)
1866 goto out_resource;
1836 WRITE32(2); 1867 WRITE32(2);
1837 WRITE32(word0); 1868 WRITE32(word0);
1838 WRITE32(word1); 1869 WRITE32(word1);
1839 } else { 1870 } else {
1871 if ((buflen -= 16) < 0)
1872 goto out_resource;
1840 WRITE32(3); 1873 WRITE32(3);
1841 WRITE32(word0); 1874 WRITE32(word0);
1842 WRITE32(word1); 1875 WRITE32(word1);
@@ -2303,8 +2336,6 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2303 case nfserr_resource: 2336 case nfserr_resource:
2304 nfserr = nfserr_toosmall; 2337 nfserr = nfserr_toosmall;
2305 goto fail; 2338 goto fail;
2306 case nfserr_dropit:
2307 goto fail;
2308 case nfserr_noent: 2339 case nfserr_noent:
2309 goto skip_entry; 2340 goto skip_entry;
2310 default: 2341 default:
@@ -2359,6 +2390,21 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2359 return nfserr; 2390 return nfserr;
2360} 2391}
2361 2392
2393static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2394{
2395 __be32 *p;
2396
2397 if (!nfserr) {
2398 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
2399 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
2400 WRITE32(bcts->dir);
2401 /* XXX: ? */
2402 WRITE32(0);
2403 ADJUST_ARGS();
2404 }
2405 return nfserr;
2406}
2407
2362static __be32 2408static __be32
2363nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) 2409nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2364{ 2410{
@@ -2820,11 +2866,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2820} 2866}
2821 2867
2822static __be32 2868static __be32
2823nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, 2869nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
2824 struct nfsd4_secinfo *secinfo) 2870 __be32 nfserr,struct svc_export *exp)
2825{ 2871{
2826 int i = 0; 2872 int i = 0;
2827 struct svc_export *exp = secinfo->si_exp;
2828 u32 nflavs; 2873 u32 nflavs;
2829 struct exp_flavor_info *flavs; 2874 struct exp_flavor_info *flavs;
2830 struct exp_flavor_info def_flavs[2]; 2875 struct exp_flavor_info def_flavs[2];
@@ -2886,6 +2931,20 @@ out:
2886 return nfserr; 2931 return nfserr;
2887} 2932}
2888 2933
2934static __be32
2935nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
2936 struct nfsd4_secinfo *secinfo)
2937{
2938 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
2939}
2940
2941static __be32
2942nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
2943 struct nfsd4_secinfo_no_name *secinfo)
2944{
2945 return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
2946}
2947
2889/* 2948/*
2890 * The SETATTR encode routine is special -- it always encodes a bitmap, 2949 * The SETATTR encode routine is special -- it always encodes a bitmap,
2891 * regardless of the error status. 2950 * regardless of the error status.
@@ -3056,7 +3115,7 @@ nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
3056 return nfserr; 3115 return nfserr;
3057} 3116}
3058 3117
3059__be32 3118static __be32
3060nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3119nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3061 struct nfsd4_sequence *seq) 3120 struct nfsd4_sequence *seq)
3062{ 3121{
@@ -3070,13 +3129,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3070 WRITE32(seq->seqid); 3129 WRITE32(seq->seqid);
3071 WRITE32(seq->slotid); 3130 WRITE32(seq->slotid);
3072 WRITE32(seq->maxslots); 3131 WRITE32(seq->maxslots);
3073 /* 3132 /* For now: target_maxslots = maxslots */
3074 * FIXME: for now:
3075 * target_maxslots = maxslots
3076 * status_flags = 0
3077 */
3078 WRITE32(seq->maxslots); 3133 WRITE32(seq->maxslots);
3079 WRITE32(0); 3134 WRITE32(seq->status_flags);
3080 3135
3081 ADJUST_ARGS(); 3136 ADJUST_ARGS();
3082 resp->cstate.datap = p; /* DRC cache data pointer */ 3137 resp->cstate.datap = p; /* DRC cache data pointer */
@@ -3137,7 +3192,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3137 3192
3138 /* NFSv4.1 operations */ 3193 /* NFSv4.1 operations */
3139 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, 3194 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop,
3140 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop, 3195 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3141 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3196 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
3142 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3197 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
3143 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3198 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session,
@@ -3148,7 +3203,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3148 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, 3203 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
3149 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, 3204 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
3150 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, 3205 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
3151 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop, 3206 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
3152 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, 3207 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
3153 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, 3208 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
3154 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3209 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop,