forked from Minki/linux
Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from Bruce Fields: "This includes miscellaneous bugfixes and cleanup and a performance fix for write-heavy NFSv4 workloads. (The most significant nfsd-relevant change this time is actually in the delegation patches that went through Viro, fixing a long-standing bug that can cause NFSv4 clients to miss updates made by non-nfs users of the filesystem. Those enable some followup nfsd patches which I have queued locally, but those can wait till 3.14)" * 'nfsd-next' of git://linux-nfs.org/~bfields/linux: (24 commits) nfsd: export proper maximum file size to the client nfsd4: improve write performance with better sendspace reservations svcrpc: remove an unnecessary assignment sunrpc: comment typo fix Revert "nfsd: remove_stid can be incorporated into nfs4_put_delegation" nfsd4: fix discarded security labels on setattr NFSD: Add support for NFS v4.2 operation checking nfsd4: nfsd_shutdown_net needs state lock NFSD: Combine decode operations for v4 and v4.1 nfsd: -EINVAL on invalid anonuid/gid instead of silent failure nfsd: return better errors to exportfs nfsd: fh_update should error out in unexpected cases nfsd4: need to destroy revoked delegations in destroy_client nfsd: no need to unhash_stid before free nfsd: remove_stid can be incorporated into nfs4_put_delegation nfsd: nfs4_open_delegation needs to remove_stid rather than unhash_stid nfsd: nfs4_free_stid nfsd: fix Kconfig syntax sunrpc: trim off EC bytes in GSSAPI v2 unwrap gss_krb5: document that we ignore sequence number ...
This commit is contained in:
commit
449bf8d03c
@ -95,7 +95,7 @@ config NFSD_V4_SECURITY_LABEL
|
||||
Smack policies on NFSv4 files, say N.
|
||||
|
||||
WARNING: there is still a chance of backwards-incompatible protocol changes.
|
||||
For now we recommend "Y" only for developers and testers."
|
||||
For now we recommend "Y" only for developers and testers.
|
||||
|
||||
config NFSD_FAULT_INJECTION
|
||||
bool "NFS server manual fault injection"
|
||||
|
@ -536,16 +536,12 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
|
||||
if (err)
|
||||
goto out3;
|
||||
exp.ex_anon_uid= make_kuid(&init_user_ns, an_int);
|
||||
if (!uid_valid(exp.ex_anon_uid))
|
||||
goto out3;
|
||||
|
||||
/* anon gid */
|
||||
err = get_int(&mesg, &an_int);
|
||||
if (err)
|
||||
goto out3;
|
||||
exp.ex_anon_gid= make_kgid(&init_user_ns, an_int);
|
||||
if (!gid_valid(exp.ex_anon_gid))
|
||||
goto out3;
|
||||
|
||||
/* fsid */
|
||||
err = get_int(&mesg, &an_int);
|
||||
@ -583,6 +579,26 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
|
||||
exp.ex_uuid);
|
||||
if (err)
|
||||
goto out4;
|
||||
/*
|
||||
* No point caching this if it would immediately expire.
|
||||
* Also, this protects exportfs's dummy export from the
|
||||
* anon_uid/anon_gid checks:
|
||||
*/
|
||||
if (exp.h.expiry_time < seconds_since_boot())
|
||||
goto out4;
|
||||
/*
|
||||
* For some reason exportfs has been passing down an
|
||||
* invalid (-1) uid & gid on the "dummy" export which it
|
||||
* uses to test export support. To make sure exportfs
|
||||
* sees errors from check_export we therefore need to
|
||||
* delay these checks till after check_export:
|
||||
*/
|
||||
err = -EINVAL;
|
||||
if (!uid_valid(exp.ex_anon_uid))
|
||||
goto out4;
|
||||
if (!gid_valid(exp.ex_anon_gid))
|
||||
goto out4;
|
||||
err = 0;
|
||||
}
|
||||
|
||||
expp = svc_export_lookup(&exp);
|
||||
|
@ -402,11 +402,16 @@ static void remove_stid(struct nfs4_stid *s)
|
||||
idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
|
||||
}
|
||||
|
||||
static void nfs4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s)
|
||||
{
|
||||
kmem_cache_free(slab, s);
|
||||
}
|
||||
|
||||
void
|
||||
nfs4_put_delegation(struct nfs4_delegation *dp)
|
||||
{
|
||||
if (atomic_dec_and_test(&dp->dl_count)) {
|
||||
kmem_cache_free(deleg_slab, dp);
|
||||
nfs4_free_stid(deleg_slab, &dp->dl_stid);
|
||||
num_delegations--;
|
||||
}
|
||||
}
|
||||
@ -610,7 +615,7 @@ static void close_generic_stateid(struct nfs4_ol_stateid *stp)
|
||||
static void free_generic_stateid(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
remove_stid(&stp->st_stid);
|
||||
kmem_cache_free(stateid_slab, stp);
|
||||
nfs4_free_stid(stateid_slab, &stp->st_stid);
|
||||
}
|
||||
|
||||
static void release_lock_stateid(struct nfs4_ol_stateid *stp)
|
||||
@ -668,7 +673,6 @@ static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
|
||||
static void release_open_stateid(struct nfs4_ol_stateid *stp)
|
||||
{
|
||||
unhash_open_stateid(stp);
|
||||
unhash_stid(&stp->st_stid);
|
||||
free_generic_stateid(stp);
|
||||
}
|
||||
|
||||
@ -690,7 +694,6 @@ static void release_last_closed_stateid(struct nfs4_openowner *oo)
|
||||
struct nfs4_ol_stateid *s = oo->oo_last_closed_stid;
|
||||
|
||||
if (s) {
|
||||
unhash_stid(&s->st_stid);
|
||||
free_generic_stateid(s);
|
||||
oo->oo_last_closed_stid = NULL;
|
||||
}
|
||||
@ -1127,6 +1130,11 @@ destroy_client(struct nfs4_client *clp)
|
||||
dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
|
||||
destroy_delegation(dp);
|
||||
}
|
||||
list_splice_init(&clp->cl_revoked, &reaplist);
|
||||
while (!list_empty(&reaplist)) {
|
||||
dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
|
||||
destroy_revoked_delegation(dp);
|
||||
}
|
||||
while (!list_empty(&clp->cl_openowners)) {
|
||||
oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
|
||||
release_openowner(oo);
|
||||
@ -3154,7 +3162,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
|
||||
open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
|
||||
return;
|
||||
out_free:
|
||||
unhash_stid(&dp->dl_stid);
|
||||
remove_stid(&dp->dl_stid);
|
||||
nfs4_put_delegation(dp);
|
||||
out_no_deleg:
|
||||
open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
|
||||
@ -3995,10 +4003,9 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
|
||||
nfsd4_close_open_stateid(stp);
|
||||
|
||||
if (cstate->minorversion) {
|
||||
unhash_stid(&stp->st_stid);
|
||||
if (cstate->minorversion)
|
||||
free_generic_stateid(stp);
|
||||
} else
|
||||
else
|
||||
oo->oo_last_closed_stid = stp;
|
||||
|
||||
if (list_empty(&oo->oo_owner.so_stateids)) {
|
||||
@ -5119,7 +5126,6 @@ out_recovery:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* should be called with the state lock held */
|
||||
void
|
||||
nfs4_state_shutdown_net(struct net *net)
|
||||
{
|
||||
@ -5130,6 +5136,7 @@ nfs4_state_shutdown_net(struct net *net)
|
||||
cancel_delayed_work_sync(&nn->laundromat_work);
|
||||
locks_end_grace(&nn->nfsd4_manager);
|
||||
|
||||
nfs4_lock_state();
|
||||
INIT_LIST_HEAD(&reaplist);
|
||||
spin_lock(&recall_lock);
|
||||
list_for_each_safe(pos, next, &nn->del_recall_lru) {
|
||||
@ -5144,6 +5151,7 @@ nfs4_state_shutdown_net(struct net *net)
|
||||
|
||||
nfsd4_client_tracking_exit(net);
|
||||
nfs4_state_destroy_net(net);
|
||||
nfs4_unlock_state();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -411,6 +411,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
||||
label->data = kzalloc(dummy32 + 1, GFP_KERNEL);
|
||||
if (!label->data)
|
||||
return nfserr_jukebox;
|
||||
label->len = dummy32;
|
||||
defer_free(argp, kfree, label->data);
|
||||
memcpy(label->data, buf, dummy32);
|
||||
}
|
||||
@ -945,13 +946,16 @@ static __be32
|
||||
nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
|
||||
{
|
||||
DECODE_HEAD;
|
||||
|
||||
|
||||
if (argp->minorversion >= 1)
|
||||
return nfserr_notsupp;
|
||||
|
||||
status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
|
||||
if (status)
|
||||
return status;
|
||||
READ_BUF(4);
|
||||
READ32(open_conf->oc_seqid);
|
||||
|
||||
|
||||
DECODE_TAIL;
|
||||
}
|
||||
|
||||
@ -990,6 +994,14 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
|
||||
DECODE_TAIL;
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
|
||||
{
|
||||
if (argp->minorversion == 0)
|
||||
return nfs_ok;
|
||||
return nfserr_notsupp;
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
|
||||
{
|
||||
@ -1061,6 +1073,9 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
|
||||
{
|
||||
DECODE_HEAD;
|
||||
|
||||
if (argp->minorversion >= 1)
|
||||
return nfserr_notsupp;
|
||||
|
||||
READ_BUF(sizeof(clientid_t));
|
||||
COPYMEM(clientid, sizeof(clientid_t));
|
||||
|
||||
@ -1111,6 +1126,9 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
|
||||
{
|
||||
DECODE_HEAD;
|
||||
|
||||
if (argp->minorversion >= 1)
|
||||
return nfserr_notsupp;
|
||||
|
||||
READ_BUF(NFS4_VERIFIER_SIZE);
|
||||
COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
|
||||
|
||||
@ -1137,6 +1155,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
|
||||
{
|
||||
DECODE_HEAD;
|
||||
|
||||
if (argp->minorversion >= 1)
|
||||
return nfserr_notsupp;
|
||||
|
||||
READ_BUF(8 + NFS4_VERIFIER_SIZE);
|
||||
COPYMEM(&scd_c->sc_clientid, 8);
|
||||
COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
|
||||
@ -1220,6 +1241,9 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
|
||||
{
|
||||
DECODE_HEAD;
|
||||
|
||||
if (argp->minorversion >= 1)
|
||||
return nfserr_notsupp;
|
||||
|
||||
READ_BUF(12);
|
||||
COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
|
||||
READ32(rlockowner->rl_owner.len);
|
||||
@ -1519,7 +1543,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
|
||||
[OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
|
||||
[OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
|
||||
[OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
|
||||
[OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh,
|
||||
[OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_READ] = (nfsd4_dec)nfsd4_decode_read,
|
||||
[OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
|
||||
@ -1536,46 +1560,6 @@ static nfsd4_dec nfsd4_dec_ops[] = {
|
||||
[OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
|
||||
[OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
|
||||
[OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
|
||||
};
|
||||
|
||||
static nfsd4_dec nfsd41_dec_ops[] = {
|
||||
[OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
|
||||
[OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
|
||||
[OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
|
||||
[OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
|
||||
[OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
|
||||
[OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
|
||||
[OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
|
||||
[OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
|
||||
[OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
|
||||
[OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
|
||||
[OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
|
||||
[OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
|
||||
[OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
|
||||
[OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
|
||||
[OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
|
||||
[OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_READ] = (nfsd4_dec)nfsd4_decode_read,
|
||||
[OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
|
||||
[OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
|
||||
[OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
|
||||
[OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
|
||||
[OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
|
||||
[OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
|
||||
[OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
[OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
|
||||
[OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
|
||||
[OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,
|
||||
|
||||
/* new operations for NFSv4.1 */
|
||||
[OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
|
||||
@ -1599,24 +1583,53 @@ static nfsd4_dec nfsd41_dec_ops[] = {
|
||||
[OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
|
||||
};
|
||||
|
||||
struct nfsd4_minorversion_ops {
|
||||
nfsd4_dec *decoders;
|
||||
int nops;
|
||||
};
|
||||
static inline bool
|
||||
nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
|
||||
{
|
||||
if (op->opnum < FIRST_NFS4_OP)
|
||||
return false;
|
||||
else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP)
|
||||
return false;
|
||||
else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP)
|
||||
return false;
|
||||
else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
|
||||
[0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
|
||||
[1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
|
||||
[2] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
|
||||
};
|
||||
/*
|
||||
* Return a rough estimate of the maximum possible reply size. Note the
|
||||
* estimate includes rpc headers so is meant to be passed to
|
||||
* svc_reserve, not svc_reserve_auth.
|
||||
*
|
||||
* Also note the current compound encoding permits only one operation to
|
||||
* use pages beyond the first one, so the maximum possible length is the
|
||||
* maximum over these values, not the sum.
|
||||
*/
|
||||
static int nfsd4_max_reply(u32 opnum)
|
||||
{
|
||||
switch (opnum) {
|
||||
case OP_READLINK:
|
||||
case OP_READDIR:
|
||||
/*
|
||||
* Both of these ops take a single page for data and put
|
||||
* the head and tail in another page:
|
||||
*/
|
||||
return 2 * PAGE_SIZE;
|
||||
case OP_READ:
|
||||
return INT_MAX;
|
||||
default:
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
||||
{
|
||||
DECODE_HEAD;
|
||||
struct nfsd4_op *op;
|
||||
struct nfsd4_minorversion_ops *ops;
|
||||
bool cachethis = false;
|
||||
int max_reply = PAGE_SIZE;
|
||||
int i;
|
||||
|
||||
READ_BUF(4);
|
||||
@ -1640,10 +1653,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
||||
}
|
||||
}
|
||||
|
||||
if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion))
|
||||
if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
|
||||
argp->opcnt = 0;
|
||||
|
||||
ops = &nfsd4_minorversion[argp->minorversion];
|
||||
for (i = 0; i < argp->opcnt; i++) {
|
||||
op = &argp->ops[i];
|
||||
op->replay = NULL;
|
||||
@ -1651,8 +1663,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
||||
READ_BUF(4);
|
||||
READ32(op->opnum);
|
||||
|
||||
if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
|
||||
op->status = ops->decoders[op->opnum](argp, &op->u);
|
||||
if (nfsd4_opnum_in_range(argp, op))
|
||||
op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
|
||||
else {
|
||||
op->opnum = OP_ILLEGAL;
|
||||
op->status = nfserr_op_illegal;
|
||||
@ -1667,10 +1679,14 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
||||
* op in the compound wants to be cached:
|
||||
*/
|
||||
cachethis |= nfsd4_cache_this_op(op);
|
||||
|
||||
max_reply = max(max_reply, nfsd4_max_reply(op->opnum));
|
||||
}
|
||||
/* Sessions make the DRC unnecessary: */
|
||||
if (argp->minorversion)
|
||||
cachethis = false;
|
||||
if (max_reply != INT_MAX)
|
||||
svc_reserve(argp->rqstp, max_reply);
|
||||
argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
|
||||
|
||||
DECODE_TAIL;
|
||||
@ -2375,7 +2391,7 @@ out_acl:
|
||||
if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
|
||||
if ((buflen -= 8) < 0)
|
||||
goto out_resource;
|
||||
WRITE64(~(u64)0);
|
||||
WRITE64(exp->ex_path.mnt->mnt_sb->s_maxbytes);
|
||||
}
|
||||
if (bmval0 & FATTR4_WORD0_MAXLINK) {
|
||||
if ((buflen -= 4) < 0)
|
||||
|
@ -598,22 +598,20 @@ fh_update(struct svc_fh *fhp)
|
||||
_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
|
||||
} else {
|
||||
if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
_fh_update(fhp, fhp->fh_export, dentry);
|
||||
if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
|
||||
return nfserr_opnotsupp;
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
|
||||
out_bad:
|
||||
printk(KERN_ERR "fh_update: fh not verified!\n");
|
||||
goto out;
|
||||
return nfserr_serverfault;
|
||||
out_negative:
|
||||
printk(KERN_ERR "fh_update: %pd2 still negative!\n",
|
||||
dentry);
|
||||
goto out;
|
||||
return nfserr_serverfault;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -118,6 +118,9 @@ Needs to be updated if more operations are defined in future.*/
|
||||
|
||||
#define FIRST_NFS4_OP OP_ACCESS
|
||||
#define LAST_NFS4_OP OP_RECLAIM_COMPLETE
|
||||
#define LAST_NFS40_OP OP_RELEASE_LOCKOWNER
|
||||
#define LAST_NFS41_OP OP_RECLAIM_COMPLETE
|
||||
#define LAST_NFS42_OP OP_RECLAIM_COMPLETE
|
||||
|
||||
enum nfsstat4 {
|
||||
NFS4_OK = 0,
|
||||
|
@ -150,7 +150,6 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
|
||||
struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
|
||||
.data = cksumdata};
|
||||
s32 now;
|
||||
u64 seqnum;
|
||||
u8 *ptr = read_token->data;
|
||||
u8 *cksumkey;
|
||||
u8 flags;
|
||||
@ -197,9 +196,10 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
|
||||
if (now > ctx->endtime)
|
||||
return GSS_S_CONTEXT_EXPIRED;
|
||||
|
||||
/* do sequencing checks */
|
||||
|
||||
seqnum = be64_to_cpup((__be64 *)ptr + 8);
|
||||
/*
|
||||
* NOTE: the sequence number at ptr + 8 is skipped, rpcsec_gss
|
||||
* doesn't want it checked; see page 6 of rfc 2203.
|
||||
*/
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
@ -489,7 +489,6 @@ static u32
|
||||
gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
|
||||
{
|
||||
s32 now;
|
||||
u64 seqnum;
|
||||
u8 *ptr;
|
||||
u8 flags = 0x00;
|
||||
u16 ec, rrc;
|
||||
@ -525,7 +524,10 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
|
||||
ec = be16_to_cpup((__be16 *)(ptr + 4));
|
||||
rrc = be16_to_cpup((__be16 *)(ptr + 6));
|
||||
|
||||
seqnum = be64_to_cpup((__be64 *)(ptr + 8));
|
||||
/*
|
||||
* NOTE: the sequence number at ptr + 8 is skipped, rpcsec_gss
|
||||
* doesn't want it checked; see page 6 of rfc 2203.
|
||||
*/
|
||||
|
||||
if (rrc != 0)
|
||||
rotate_left(offset + 16, buf, rrc);
|
||||
@ -574,8 +576,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
|
||||
buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip;
|
||||
buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip;
|
||||
|
||||
/* Trim off the checksum blob */
|
||||
xdr_buf_trim(buf, GSS_KRB5_TOK_HDR_LEN + tailskip);
|
||||
/* Trim off the trailing "extra count" and checksum blob */
|
||||
xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip);
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,8 @@ int gssp_accept_sec_context_upcall(struct net *net,
|
||||
if (res.context_handle) {
|
||||
data->out_handle = rctxh.exported_context_token;
|
||||
data->mech_oid.len = rctxh.mech.len;
|
||||
memcpy(data->mech_oid.data, rctxh.mech.data,
|
||||
if (rctxh.mech.data)
|
||||
memcpy(data->mech_oid.data, rctxh.mech.data,
|
||||
data->mech_oid.len);
|
||||
client_name = rctxh.src_name.display_name;
|
||||
}
|
||||
|
@ -559,6 +559,8 @@ static int gssx_enc_cred(struct xdr_stream *xdr,
|
||||
|
||||
/* cred->elements */
|
||||
err = dummy_enc_credel_array(xdr, &cred->elements);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* cred->cred_handle_reference */
|
||||
err = gssx_enc_buffer(xdr, &cred->cred_handle_reference);
|
||||
@ -740,22 +742,20 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req,
|
||||
goto done;
|
||||
|
||||
/* arg->context_handle */
|
||||
if (arg->context_handle) {
|
||||
if (arg->context_handle)
|
||||
err = gssx_enc_ctx(xdr, arg->context_handle);
|
||||
if (err)
|
||||
goto done;
|
||||
} else {
|
||||
else
|
||||
err = gssx_enc_bool(xdr, 0);
|
||||
}
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
/* arg->cred_handle */
|
||||
if (arg->cred_handle) {
|
||||
if (arg->cred_handle)
|
||||
err = gssx_enc_cred(xdr, arg->cred_handle);
|
||||
if (err)
|
||||
goto done;
|
||||
} else {
|
||||
else
|
||||
err = gssx_enc_bool(xdr, 0);
|
||||
}
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
/* arg->input_token */
|
||||
err = gssx_enc_in_token(xdr, &arg->input_token);
|
||||
@ -763,13 +763,12 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req,
|
||||
goto done;
|
||||
|
||||
/* arg->input_cb */
|
||||
if (arg->input_cb) {
|
||||
if (arg->input_cb)
|
||||
err = gssx_enc_cb(xdr, arg->input_cb);
|
||||
if (err)
|
||||
goto done;
|
||||
} else {
|
||||
else
|
||||
err = gssx_enc_bool(xdr, 0);
|
||||
}
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
err = gssx_enc_bool(xdr, arg->ret_deleg_cred);
|
||||
if (err)
|
||||
|
@ -1167,8 +1167,8 @@ static int gss_proxy_save_rsc(struct cache_detail *cd,
|
||||
if (!ud->found_creds) {
|
||||
/* userspace seem buggy, we should always get at least a
|
||||
* mapping to nobody */
|
||||
dprintk("RPC: No creds found, marking Negative!\n");
|
||||
set_bit(CACHE_NEGATIVE, &rsci.h.flags);
|
||||
dprintk("RPC: No creds found!\n");
|
||||
goto out;
|
||||
} else {
|
||||
|
||||
/* steal creds */
|
||||
|
@ -1104,8 +1104,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
|
||||
rqstp->rq_vers = vers = svc_getnl(argv); /* version number */
|
||||
rqstp->rq_proc = proc = svc_getnl(argv); /* procedure number */
|
||||
|
||||
progp = serv->sv_program;
|
||||
|
||||
for (progp = serv->sv_program; progp; progp = progp->pg_next)
|
||||
if (prog == progp->pg_prog)
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user