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.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b0bfbda375e1..864498f8f2d9 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -56,6 +56,7 @@
56#include <linux/nfsd_idmap.h> 56#include <linux/nfsd_idmap.h>
57#include <linux/nfs4.h> 57#include <linux/nfs4.h>
58#include <linux/nfs4_acl.h> 58#include <linux/nfs4_acl.h>
59#include <linux/sunrpc/gss_api.h>
59 60
60#define NFSDDBG_FACILITY NFSDDBG_XDR 61#define NFSDDBG_FACILITY NFSDDBG_XDR
61 62
@@ -819,6 +820,23 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
819} 820}
820 821
821static __be32 822static __be32
823nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
824 struct nfsd4_secinfo *secinfo)
825{
826 DECODE_HEAD;
827
828 READ_BUF(4);
829 READ32(secinfo->si_namelen);
830 READ_BUF(secinfo->si_namelen);
831 SAVEMEM(secinfo->si_name, secinfo->si_namelen);
832 status = check_filename(secinfo->si_name, secinfo->si_namelen,
833 nfserr_noent);
834 if (status)
835 return status;
836 DECODE_TAIL;
837}
838
839static __be32
822nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 840nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
823{ 841{
824 DECODE_HEAD; 842 DECODE_HEAD;
@@ -1131,6 +1149,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1131 case OP_SAVEFH: 1149 case OP_SAVEFH:
1132 op->status = nfs_ok; 1150 op->status = nfs_ok;
1133 break; 1151 break;
1152 case OP_SECINFO:
1153 op->status = nfsd4_decode_secinfo(argp, &op->u.secinfo);
1154 break;
1134 case OP_SETATTR: 1155 case OP_SETATTR:
1135 op->status = nfsd4_decode_setattr(argp, &op->u.setattr); 1156 op->status = nfsd4_decode_setattr(argp, &op->u.setattr);
1136 break; 1157 break;
@@ -1847,11 +1868,19 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
1847 if (d_mountpoint(dentry)) { 1868 if (d_mountpoint(dentry)) {
1848 int err; 1869 int err;
1849 1870
1871 /*
1872 * Why the heck aren't we just using nfsd_lookup??
1873 * Different "."/".." handling? Something else?
1874 * At least, add a comment here to explain....
1875 */
1850 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp); 1876 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
1851 if (err) { 1877 if (err) {
1852 nfserr = nfserrno(err); 1878 nfserr = nfserrno(err);
1853 goto out_put; 1879 goto out_put;
1854 } 1880 }
1881 nfserr = check_nfsd_access(exp, cd->rd_rqstp);
1882 if (nfserr)
1883 goto out_put;
1855 1884
1856 } 1885 }
1857 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, 1886 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
@@ -2419,6 +2448,49 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2419 } 2448 }
2420} 2449}
2421 2450
2451static void
2452nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, int nfserr,
2453 struct nfsd4_secinfo *secinfo)
2454{
2455 int i = 0;
2456 struct svc_export *exp = secinfo->si_exp;
2457 ENCODE_HEAD;
2458
2459 if (nfserr)
2460 goto out;
2461 RESERVE_SPACE(4);
2462 WRITE32(exp->ex_nflavors);
2463 ADJUST_ARGS();
2464 for (i = 0; i < exp->ex_nflavors; i++) {
2465 u32 flav = exp->ex_flavors[i].pseudoflavor;
2466 struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
2467
2468 if (gm) {
2469 RESERVE_SPACE(4);
2470 WRITE32(RPC_AUTH_GSS);
2471 ADJUST_ARGS();
2472 RESERVE_SPACE(4 + gm->gm_oid.len);
2473 WRITE32(gm->gm_oid.len);
2474 WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
2475 ADJUST_ARGS();
2476 RESERVE_SPACE(4);
2477 WRITE32(0); /* qop */
2478 ADJUST_ARGS();
2479 RESERVE_SPACE(4);
2480 WRITE32(gss_pseudoflavor_to_service(gm, flav));
2481 ADJUST_ARGS();
2482 gss_mech_put(gm);
2483 } else {
2484 RESERVE_SPACE(4);
2485 WRITE32(flav);
2486 ADJUST_ARGS();
2487 }
2488 }
2489out:
2490 if (exp)
2491 exp_put(exp);
2492}
2493
2422/* 2494/*
2423 * The SETATTR encode routine is special -- it always encodes a bitmap, 2495 * The SETATTR encode routine is special -- it always encodes a bitmap,
2424 * regardless of the error status. 2496 * regardless of the error status.
@@ -2559,6 +2631,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2559 break; 2631 break;
2560 case OP_SAVEFH: 2632 case OP_SAVEFH:
2561 break; 2633 break;
2634 case OP_SECINFO:
2635 nfsd4_encode_secinfo(resp, op->status, &op->u.secinfo);
2636 break;
2562 case OP_SETATTR: 2637 case OP_SETATTR:
2563 nfsd4_encode_setattr(resp, op->status, &op->u.setattr); 2638 nfsd4_encode_setattr(resp, op->status, &op->u.setattr);
2564 break; 2639 break;