aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 11:32:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 11:32:58 -0400
commit419f4319495043a9507ac3e616be9ca60af09744 (patch)
tree0f747d80d11a6d4cd726ad6556839d5cd40b23ac /net
parentfb21affa49204acd409328415b49bfe90136653c (diff)
parent6eccece90b6addf80ef9e6db79b0bc873301034b (diff)
Merge branch 'for-3.5' of git://linux-nfs.org/~bfields/linux
Pull the rest of the nfsd commits from Bruce Fields: "... and then I cherry-picked the remainder of the patches from the head of my previous branch" This is the rest of the original nfsd branch, rebased without the delegation stuff that I thought really needed to be redone. I don't like rebasing things like this in general, but in this situation this was the lesser of two evils. * 'for-3.5' of git://linux-nfs.org/~bfields/linux: (50 commits) nfsd4: fix, consolidate client_has_state nfsd4: don't remove rebooted client record until confirmation nfsd4: remove some dprintk's and a comment nfsd4: return "real" sequence id in confirmed case nfsd4: fix exchange_id to return confirm flag nfsd4: clarify that renewing expired client is a bug nfsd4: simpler ordering of setclientid_confirm checks nfsd4: setclientid: remove pointless assignment nfsd4: fix error return in non-matching-creds case nfsd4: fix setclientid_confirm same_cred check nfsd4: merge 3 setclientid cases to 2 nfsd4: pull out common code from setclientid cases nfsd4: merge last two setclientid cases nfsd4: setclientid/confirm comment cleanup nfsd4: setclientid remove unnecessary terms from a logical expression nfsd4: move rq_flavor into svc_cred nfsd4: stricter cred comparison for setclientid/exchange_id nfsd4: move principal name into svc_cred nfsd4: allow removing clients not holding state nfsd4: rearrange exchange_id logic to simplify ...
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c61
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c27
-rw-r--r--net/sunrpc/rpcb_clnt.c12
-rw-r--r--net/sunrpc/svc.c23
-rw-r--r--net/sunrpc/svc_xprt.c4
-rw-r--r--net/sunrpc/svcauth_unix.c6
6 files changed, 75 insertions, 58 deletions
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 38f388c39dce..107c4528654f 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -381,21 +381,53 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
381} 381}
382 382
383/* 383/*
384 * We cannot currently handle tokens with rotated data. We need a 384 * We can shift data by up to LOCAL_BUF_LEN bytes in a pass. If we need
385 * generalized routine to rotate the data in place. It is anticipated 385 * to do more than that, we shift repeatedly. Kevin Coffman reports
386 * that we won't encounter rotated data in the general case. 386 * seeing 28 bytes as the value used by Microsoft clients and servers
387 * with AES, so this constant is chosen to allow handling 28 in one pass
388 * without using too much stack space.
389 *
390 * If that proves to a problem perhaps we could use a more clever
391 * algorithm.
387 */ 392 */
388static u32 393#define LOCAL_BUF_LEN 32u
389rotate_left(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, u16 rrc) 394
395static void rotate_buf_a_little(struct xdr_buf *buf, unsigned int shift)
390{ 396{
391 unsigned int realrrc = rrc % (buf->len - offset - GSS_KRB5_TOK_HDR_LEN); 397 char head[LOCAL_BUF_LEN];
398 char tmp[LOCAL_BUF_LEN];
399 unsigned int this_len, i;
400
401 BUG_ON(shift > LOCAL_BUF_LEN);
392 402
393 if (realrrc == 0) 403 read_bytes_from_xdr_buf(buf, 0, head, shift);
394 return 0; 404 for (i = 0; i + shift < buf->len; i += LOCAL_BUF_LEN) {
405 this_len = min(LOCAL_BUF_LEN, buf->len - (i + shift));
406 read_bytes_from_xdr_buf(buf, i+shift, tmp, this_len);
407 write_bytes_to_xdr_buf(buf, i, tmp, this_len);
408 }
409 write_bytes_to_xdr_buf(buf, buf->len - shift, head, shift);
410}
395 411
396 dprintk("%s: cannot process token with rotated data: " 412static void _rotate_left(struct xdr_buf *buf, unsigned int shift)
397 "rrc %u, realrrc %u\n", __func__, rrc, realrrc); 413{
398 return 1; 414 int shifted = 0;
415 int this_shift;
416
417 shift %= buf->len;
418 while (shifted < shift) {
419 this_shift = min(shift - shifted, LOCAL_BUF_LEN);
420 rotate_buf_a_little(buf, this_shift);
421 shifted += this_shift;
422 }
423}
424
425static void rotate_left(u32 base, struct xdr_buf *buf, unsigned int shift)
426{
427 struct xdr_buf subbuf;
428
429 xdr_buf_subsegment(buf, &subbuf, base, buf->len - base);
430 _rotate_left(&subbuf, shift);
399} 431}
400 432
401static u32 433static u32
@@ -495,11 +527,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
495 527
496 seqnum = be64_to_cpup((__be64 *)(ptr + 8)); 528 seqnum = be64_to_cpup((__be64 *)(ptr + 8));
497 529
498 if (rrc != 0) { 530 if (rrc != 0)
499 err = rotate_left(kctx, offset, buf, rrc); 531 rotate_left(offset + 16, buf, rrc);
500 if (err)
501 return GSS_S_FAILURE;
502 }
503 532
504 err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf, 533 err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf,
505 &headskip, &tailskip); 534 &headskip, &tailskip);
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 3089de37c433..73e957386600 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -336,7 +336,6 @@ struct rsc {
336 struct svc_cred cred; 336 struct svc_cred cred;
337 struct gss_svc_seq_data seqdata; 337 struct gss_svc_seq_data seqdata;
338 struct gss_ctx *mechctx; 338 struct gss_ctx *mechctx;
339 char *client_name;
340}; 339};
341 340
342static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old); 341static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
@@ -347,9 +346,7 @@ static void rsc_free(struct rsc *rsci)
347 kfree(rsci->handle.data); 346 kfree(rsci->handle.data);
348 if (rsci->mechctx) 347 if (rsci->mechctx)
349 gss_delete_sec_context(&rsci->mechctx); 348 gss_delete_sec_context(&rsci->mechctx);
350 if (rsci->cred.cr_group_info) 349 free_svc_cred(&rsci->cred);
351 put_group_info(rsci->cred.cr_group_info);
352 kfree(rsci->client_name);
353} 350}
354 351
355static void rsc_put(struct kref *ref) 352static void rsc_put(struct kref *ref)
@@ -387,7 +384,7 @@ rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
387 tmp->handle.data = NULL; 384 tmp->handle.data = NULL;
388 new->mechctx = NULL; 385 new->mechctx = NULL;
389 new->cred.cr_group_info = NULL; 386 new->cred.cr_group_info = NULL;
390 new->client_name = NULL; 387 new->cred.cr_principal = NULL;
391} 388}
392 389
393static void 390static void
@@ -402,8 +399,8 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
402 spin_lock_init(&new->seqdata.sd_lock); 399 spin_lock_init(&new->seqdata.sd_lock);
403 new->cred = tmp->cred; 400 new->cred = tmp->cred;
404 tmp->cred.cr_group_info = NULL; 401 tmp->cred.cr_group_info = NULL;
405 new->client_name = tmp->client_name; 402 new->cred.cr_principal = tmp->cred.cr_principal;
406 tmp->client_name = NULL; 403 tmp->cred.cr_principal = NULL;
407} 404}
408 405
409static struct cache_head * 406static struct cache_head *
@@ -501,8 +498,8 @@ static int rsc_parse(struct cache_detail *cd,
501 /* get client name */ 498 /* get client name */
502 len = qword_get(&mesg, buf, mlen); 499 len = qword_get(&mesg, buf, mlen);
503 if (len > 0) { 500 if (len > 0) {
504 rsci.client_name = kstrdup(buf, GFP_KERNEL); 501 rsci.cred.cr_principal = kstrdup(buf, GFP_KERNEL);
505 if (!rsci.client_name) 502 if (!rsci.cred.cr_principal)
506 goto out; 503 goto out;
507 } 504 }
508 505
@@ -932,16 +929,6 @@ struct gss_svc_data {
932 struct rsc *rsci; 929 struct rsc *rsci;
933}; 930};
934 931
935char *svc_gss_principal(struct svc_rqst *rqstp)
936{
937 struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data;
938
939 if (gd && gd->rsci)
940 return gd->rsci->client_name;
941 return NULL;
942}
943EXPORT_SYMBOL_GPL(svc_gss_principal);
944
945static int 932static int
946svcauth_gss_set_client(struct svc_rqst *rqstp) 933svcauth_gss_set_client(struct svc_rqst *rqstp)
947{ 934{
@@ -1220,7 +1207,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1220 } 1207 }
1221 svcdata->rsci = rsci; 1208 svcdata->rsci = rsci;
1222 cache_get(&rsci->h); 1209 cache_get(&rsci->h);
1223 rqstp->rq_flavor = gss_svc_to_pseudoflavor( 1210 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor(
1224 rsci->mechctx->mech_type, gc->gc_svc); 1211 rsci->mechctx->mech_type, gc->gc_svc);
1225 ret = SVC_OK; 1212 ret = SVC_OK;
1226 goto out; 1213 goto out;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 3c0653439f3d..92509ffe15fc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -180,14 +180,16 @@ void rpcb_put_local(struct net *net)
180 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 180 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
181 struct rpc_clnt *clnt = sn->rpcb_local_clnt; 181 struct rpc_clnt *clnt = sn->rpcb_local_clnt;
182 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4; 182 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
183 int shutdown; 183 int shutdown = 0;
184 184
185 spin_lock(&sn->rpcb_clnt_lock); 185 spin_lock(&sn->rpcb_clnt_lock);
186 if (--sn->rpcb_users == 0) { 186 if (sn->rpcb_users) {
187 sn->rpcb_local_clnt = NULL; 187 if (--sn->rpcb_users == 0) {
188 sn->rpcb_local_clnt4 = NULL; 188 sn->rpcb_local_clnt = NULL;
189 sn->rpcb_local_clnt4 = NULL;
190 }
191 shutdown = !sn->rpcb_users;
189 } 192 }
190 shutdown = !sn->rpcb_users;
191 spin_unlock(&sn->rpcb_clnt_lock); 193 spin_unlock(&sn->rpcb_clnt_lock);
192 194
193 if (shutdown) { 195 if (shutdown) {
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 017c0117d154..7e9baaa1e543 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -407,6 +407,14 @@ static int svc_uses_rpcbind(struct svc_serv *serv)
407 return 0; 407 return 0;
408} 408}
409 409
410int svc_bind(struct svc_serv *serv, struct net *net)
411{
412 if (!svc_uses_rpcbind(serv))
413 return 0;
414 return svc_rpcb_setup(serv, net);
415}
416EXPORT_SYMBOL_GPL(svc_bind);
417
410/* 418/*
411 * Create an RPC service 419 * Create an RPC service
412 */ 420 */
@@ -471,15 +479,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
471 spin_lock_init(&pool->sp_lock); 479 spin_lock_init(&pool->sp_lock);
472 } 480 }
473 481
474 if (svc_uses_rpcbind(serv)) { 482 if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown))
475 if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) { 483 serv->sv_shutdown = svc_rpcb_cleanup;
476 kfree(serv->sv_pools);
477 kfree(serv);
478 return NULL;
479 }
480 if (!serv->sv_shutdown)
481 serv->sv_shutdown = svc_rpcb_cleanup;
482 }
483 484
484 return serv; 485 return serv;
485} 486}
@@ -536,8 +537,6 @@ EXPORT_SYMBOL_GPL(svc_shutdown_net);
536void 537void
537svc_destroy(struct svc_serv *serv) 538svc_destroy(struct svc_serv *serv)
538{ 539{
539 struct net *net = current->nsproxy->net_ns;
540
541 dprintk("svc: svc_destroy(%s, %d)\n", 540 dprintk("svc: svc_destroy(%s, %d)\n",
542 serv->sv_program->pg_name, 541 serv->sv_program->pg_name,
543 serv->sv_nrthreads); 542 serv->sv_nrthreads);
@@ -552,8 +551,6 @@ svc_destroy(struct svc_serv *serv)
552 551
553 del_timer_sync(&serv->sv_temptimer); 552 del_timer_sync(&serv->sv_temptimer);
554 553
555 svc_shutdown_net(serv, net);
556
557 /* 554 /*
558 * The last user is gone and thus all sockets have to be destroyed to 555 * The last user is gone and thus all sockets have to be destroyed to
559 * the point. Check this. 556 * the point. Check this.
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index b98ee3514912..88f2bf671960 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -598,6 +598,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
598 598
599 /* now allocate needed pages. If we get a failure, sleep briefly */ 599 /* now allocate needed pages. If we get a failure, sleep briefly */
600 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; 600 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
601 BUG_ON(pages >= RPCSVC_MAXPAGES);
601 for (i = 0; i < pages ; i++) 602 for (i = 0; i < pages ; i++)
602 while (rqstp->rq_pages[i] == NULL) { 603 while (rqstp->rq_pages[i] == NULL) {
603 struct page *p = alloc_page(GFP_KERNEL); 604 struct page *p = alloc_page(GFP_KERNEL);
@@ -612,7 +613,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
612 rqstp->rq_pages[i] = p; 613 rqstp->rq_pages[i] = p;
613 } 614 }
614 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ 615 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */
615 BUG_ON(pages >= RPCSVC_MAXPAGES);
616 616
617 /* Make arg->head point to first page and arg->pages point to rest */ 617 /* Make arg->head point to first page and arg->pages point to rest */
618 arg = &rqstp->rq_arg; 618 arg = &rqstp->rq_arg;
@@ -973,7 +973,7 @@ void svc_close_net(struct svc_serv *serv, struct net *net)
973 svc_clear_pools(serv, net); 973 svc_clear_pools(serv, net);
974 /* 974 /*
975 * At this point the sp_sockets lists will stay empty, since 975 * At this point the sp_sockets lists will stay empty, since
976 * svc_enqueue will not add new entries without taking the 976 * svc_xprt_enqueue will not add new entries without taking the
977 * sp_lock and checking XPT_BUSY. 977 * sp_lock and checking XPT_BUSY.
978 */ 978 */
979 svc_clear_list(&serv->sv_tempsocks, net); 979 svc_clear_list(&serv->sv_tempsocks, net);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 6138c925923d..2777fa896645 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -746,6 +746,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
746 struct svc_cred *cred = &rqstp->rq_cred; 746 struct svc_cred *cred = &rqstp->rq_cred;
747 747
748 cred->cr_group_info = NULL; 748 cred->cr_group_info = NULL;
749 cred->cr_principal = NULL;
749 rqstp->rq_client = NULL; 750 rqstp->rq_client = NULL;
750 751
751 if (argv->iov_len < 3*4) 752 if (argv->iov_len < 3*4)
@@ -773,7 +774,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
773 svc_putnl(resv, RPC_AUTH_NULL); 774 svc_putnl(resv, RPC_AUTH_NULL);
774 svc_putnl(resv, 0); 775 svc_putnl(resv, 0);
775 776
776 rqstp->rq_flavor = RPC_AUTH_NULL; 777 rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
777 return SVC_OK; 778 return SVC_OK;
778} 779}
779 780
@@ -811,6 +812,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
811 int len = argv->iov_len; 812 int len = argv->iov_len;
812 813
813 cred->cr_group_info = NULL; 814 cred->cr_group_info = NULL;
815 cred->cr_principal = NULL;
814 rqstp->rq_client = NULL; 816 rqstp->rq_client = NULL;
815 817
816 if ((len -= 3*4) < 0) 818 if ((len -= 3*4) < 0)
@@ -847,7 +849,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
847 svc_putnl(resv, RPC_AUTH_NULL); 849 svc_putnl(resv, RPC_AUTH_NULL);
848 svc_putnl(resv, 0); 850 svc_putnl(resv, 0);
849 851
850 rqstp->rq_flavor = RPC_AUTH_UNIX; 852 rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
851 return SVC_OK; 853 return SVC_OK;
852 854
853badcred: 855badcred: