diff options
Diffstat (limited to 'net/sunrpc/auth_gss/auth_gss.c')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 12c485982814..5daf6cc4faea 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -417,7 +417,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | |||
417 | gss_msg->msg.len += len; | 417 | gss_msg->msg.len += len; |
418 | } | 418 | } |
419 | if (mech->gm_upcall_enctypes) { | 419 | if (mech->gm_upcall_enctypes) { |
420 | len = sprintf(p, mech->gm_upcall_enctypes); | 420 | len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes); |
421 | p += len; | 421 | p += len; |
422 | gss_msg->msg.len += len; | 422 | gss_msg->msg.len += len; |
423 | } | 423 | } |
@@ -520,7 +520,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
520 | warn_gssd(); | 520 | warn_gssd(); |
521 | task->tk_timeout = 15*HZ; | 521 | task->tk_timeout = 15*HZ; |
522 | rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL); | 522 | rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL); |
523 | return 0; | 523 | return -EAGAIN; |
524 | } | 524 | } |
525 | if (IS_ERR(gss_msg)) { | 525 | if (IS_ERR(gss_msg)) { |
526 | err = PTR_ERR(gss_msg); | 526 | err = PTR_ERR(gss_msg); |
@@ -563,10 +563,12 @@ retry: | |||
563 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 563 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
564 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, | 564 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, |
565 | pipe_version >= 0, 15*HZ); | 565 | pipe_version >= 0, 15*HZ); |
566 | if (pipe_version < 0) { | ||
567 | warn_gssd(); | ||
568 | err = -EACCES; | ||
569 | } | ||
566 | if (err) | 570 | if (err) |
567 | goto out; | 571 | goto out; |
568 | if (pipe_version < 0) | ||
569 | warn_gssd(); | ||
570 | goto retry; | 572 | goto retry; |
571 | } | 573 | } |
572 | if (IS_ERR(gss_msg)) { | 574 | if (IS_ERR(gss_msg)) { |
@@ -575,13 +577,13 @@ retry: | |||
575 | } | 577 | } |
576 | inode = &gss_msg->inode->vfs_inode; | 578 | inode = &gss_msg->inode->vfs_inode; |
577 | for (;;) { | 579 | for (;;) { |
578 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); | 580 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); |
579 | spin_lock(&inode->i_lock); | 581 | spin_lock(&inode->i_lock); |
580 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { | 582 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { |
581 | break; | 583 | break; |
582 | } | 584 | } |
583 | spin_unlock(&inode->i_lock); | 585 | spin_unlock(&inode->i_lock); |
584 | if (signalled()) { | 586 | if (fatal_signal_pending(current)) { |
585 | err = -ERESTARTSYS; | 587 | err = -ERESTARTSYS; |
586 | goto out_intr; | 588 | goto out_intr; |
587 | } | 589 | } |
@@ -1050,7 +1052,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) | |||
1050 | out: | 1052 | out: |
1051 | if (acred->machine_cred != gss_cred->gc_machine_cred) | 1053 | if (acred->machine_cred != gss_cred->gc_machine_cred) |
1052 | return 0; | 1054 | return 0; |
1053 | return (rc->cr_uid == acred->uid); | 1055 | return rc->cr_uid == acred->uid; |
1054 | } | 1056 | } |
1055 | 1057 | ||
1056 | /* | 1058 | /* |
@@ -1231,9 +1233,19 @@ out_bad: | |||
1231 | return NULL; | 1233 | return NULL; |
1232 | } | 1234 | } |
1233 | 1235 | ||
1236 | static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, | ||
1237 | __be32 *p, void *obj) | ||
1238 | { | ||
1239 | struct xdr_stream xdr; | ||
1240 | |||
1241 | xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p); | ||
1242 | encode(rqstp, &xdr, obj); | ||
1243 | } | ||
1244 | |||
1234 | static inline int | 1245 | static inline int |
1235 | gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | 1246 | gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, |
1236 | kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) | 1247 | kxdreproc_t encode, struct rpc_rqst *rqstp, |
1248 | __be32 *p, void *obj) | ||
1237 | { | 1249 | { |
1238 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; | 1250 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; |
1239 | struct xdr_buf integ_buf; | 1251 | struct xdr_buf integ_buf; |
@@ -1249,9 +1261,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1249 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1261 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1250 | *p++ = htonl(rqstp->rq_seqno); | 1262 | *p++ = htonl(rqstp->rq_seqno); |
1251 | 1263 | ||
1252 | status = encode(rqstp, p, obj); | 1264 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1253 | if (status) | ||
1254 | return status; | ||
1255 | 1265 | ||
1256 | if (xdr_buf_subsegment(snd_buf, &integ_buf, | 1266 | if (xdr_buf_subsegment(snd_buf, &integ_buf, |
1257 | offset, snd_buf->len - offset)) | 1267 | offset, snd_buf->len - offset)) |
@@ -1325,7 +1335,8 @@ out: | |||
1325 | 1335 | ||
1326 | static inline int | 1336 | static inline int |
1327 | gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | 1337 | gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, |
1328 | kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) | 1338 | kxdreproc_t encode, struct rpc_rqst *rqstp, |
1339 | __be32 *p, void *obj) | ||
1329 | { | 1340 | { |
1330 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; | 1341 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; |
1331 | u32 offset; | 1342 | u32 offset; |
@@ -1342,9 +1353,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1342 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1353 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1343 | *p++ = htonl(rqstp->rq_seqno); | 1354 | *p++ = htonl(rqstp->rq_seqno); |
1344 | 1355 | ||
1345 | status = encode(rqstp, p, obj); | 1356 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1346 | if (status) | ||
1347 | return status; | ||
1348 | 1357 | ||
1349 | status = alloc_enc_pages(rqstp); | 1358 | status = alloc_enc_pages(rqstp); |
1350 | if (status) | 1359 | if (status) |
@@ -1394,7 +1403,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1394 | 1403 | ||
1395 | static int | 1404 | static int |
1396 | gss_wrap_req(struct rpc_task *task, | 1405 | gss_wrap_req(struct rpc_task *task, |
1397 | kxdrproc_t encode, void *rqstp, __be32 *p, void *obj) | 1406 | kxdreproc_t encode, void *rqstp, __be32 *p, void *obj) |
1398 | { | 1407 | { |
1399 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 1408 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
1400 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, | 1409 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, |
@@ -1407,12 +1416,14 @@ gss_wrap_req(struct rpc_task *task, | |||
1407 | /* The spec seems a little ambiguous here, but I think that not | 1416 | /* The spec seems a little ambiguous here, but I think that not |
1408 | * wrapping context destruction requests makes the most sense. | 1417 | * wrapping context destruction requests makes the most sense. |
1409 | */ | 1418 | */ |
1410 | status = encode(rqstp, p, obj); | 1419 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1420 | status = 0; | ||
1411 | goto out; | 1421 | goto out; |
1412 | } | 1422 | } |
1413 | switch (gss_cred->gc_service) { | 1423 | switch (gss_cred->gc_service) { |
1414 | case RPC_GSS_SVC_NONE: | 1424 | case RPC_GSS_SVC_NONE: |
1415 | status = encode(rqstp, p, obj); | 1425 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1426 | status = 0; | ||
1416 | break; | 1427 | break; |
1417 | case RPC_GSS_SVC_INTEGRITY: | 1428 | case RPC_GSS_SVC_INTEGRITY: |
1418 | status = gss_wrap_req_integ(cred, ctx, encode, | 1429 | status = gss_wrap_req_integ(cred, ctx, encode, |
@@ -1494,10 +1505,19 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1494 | return 0; | 1505 | return 0; |
1495 | } | 1506 | } |
1496 | 1507 | ||
1508 | static int | ||
1509 | gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, | ||
1510 | __be32 *p, void *obj) | ||
1511 | { | ||
1512 | struct xdr_stream xdr; | ||
1513 | |||
1514 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | ||
1515 | return decode(rqstp, &xdr, obj); | ||
1516 | } | ||
1497 | 1517 | ||
1498 | static int | 1518 | static int |
1499 | gss_unwrap_resp(struct rpc_task *task, | 1519 | gss_unwrap_resp(struct rpc_task *task, |
1500 | kxdrproc_t decode, void *rqstp, __be32 *p, void *obj) | 1520 | kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj) |
1501 | { | 1521 | { |
1502 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 1522 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
1503 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, | 1523 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, |
@@ -1528,7 +1548,7 @@ gss_unwrap_resp(struct rpc_task *task, | |||
1528 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) | 1548 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) |
1529 | + (savedlen - head->iov_len); | 1549 | + (savedlen - head->iov_len); |
1530 | out_decode: | 1550 | out_decode: |
1531 | status = decode(rqstp, p, obj); | 1551 | status = gss_unwrap_req_decode(decode, rqstp, p, obj); |
1532 | out: | 1552 | out: |
1533 | gss_put_ctx(ctx); | 1553 | gss_put_ctx(ctx); |
1534 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, | 1554 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, |