diff options
author | Simo Sorce <simo@redhat.com> | 2012-04-17 09:39:06 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-04-25 14:29:32 -0400 |
commit | fc2952a2a9f724f7d200c69a2b059ec331a80363 (patch) | |
tree | c615c18469c1052024e5f487d490db071bb1b776 /net | |
parent | f69adb2fe2553f0536ad3603828c835239d5ec3e (diff) |
SUNRPC: split upcall function to extract reusable parts
This is needed to share code between the current server upcall mechanism
and the new gssproxy upcall mechanism introduced in a following patch.
Signed-off-by: Simo Sorce <simo@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 100 |
1 files changed, 64 insertions, 36 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 1600cfb1618c..f0a0cd4470b7 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -964,16 +964,17 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) | |||
964 | } | 964 | } |
965 | 965 | ||
966 | static inline int | 966 | static inline int |
967 | gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi *rsip) | 967 | gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, |
968 | struct xdr_netobj *out_handle, int *major_status) | ||
968 | { | 969 | { |
969 | struct rsc *rsci; | 970 | struct rsc *rsci; |
970 | int rc; | 971 | int rc; |
971 | 972 | ||
972 | if (rsip->major_status != GSS_S_COMPLETE) | 973 | if (*major_status != GSS_S_COMPLETE) |
973 | return gss_write_null_verf(rqstp); | 974 | return gss_write_null_verf(rqstp); |
974 | rsci = gss_svc_searchbyctx(cd, &rsip->out_handle); | 975 | rsci = gss_svc_searchbyctx(cd, out_handle); |
975 | if (rsci == NULL) { | 976 | if (rsci == NULL) { |
976 | rsip->major_status = GSS_S_NO_CONTEXT; | 977 | *major_status = GSS_S_NO_CONTEXT; |
977 | return gss_write_null_verf(rqstp); | 978 | return gss_write_null_verf(rqstp); |
978 | } | 979 | } |
979 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); | 980 | rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN); |
@@ -981,22 +982,13 @@ gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi | |||
981 | return rc; | 982 | return rc; |
982 | } | 983 | } |
983 | 984 | ||
984 | /* | 985 | static inline int |
985 | * Having read the cred already and found we're in the context | 986 | gss_read_verf(struct rpc_gss_wire_cred *gc, |
986 | * initiation case, read the verifier and initiate (or check the results | 987 | struct kvec *argv, __be32 *authp, |
987 | * of) upcalls to userspace for help with context initiation. If | 988 | struct xdr_netobj *in_handle, |
988 | * the upcall results are available, write the verifier and result. | 989 | struct xdr_netobj *in_token) |
989 | * Otherwise, drop the request pending an answer to the upcall. | ||
990 | */ | ||
991 | static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | ||
992 | struct rpc_gss_wire_cred *gc, __be32 *authp) | ||
993 | { | 990 | { |
994 | struct kvec *argv = &rqstp->rq_arg.head[0]; | ||
995 | struct kvec *resv = &rqstp->rq_res.head[0]; | ||
996 | struct xdr_netobj tmpobj; | 991 | struct xdr_netobj tmpobj; |
997 | struct rsi *rsip, rsikey; | ||
998 | int ret; | ||
999 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1000 | 992 | ||
1001 | /* Read the verifier; should be NULL: */ | 993 | /* Read the verifier; should be NULL: */ |
1002 | *authp = rpc_autherr_badverf; | 994 | *authp = rpc_autherr_badverf; |
@@ -1006,24 +998,67 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1006 | return SVC_DENIED; | 998 | return SVC_DENIED; |
1007 | if (svc_getnl(argv) != 0) | 999 | if (svc_getnl(argv) != 0) |
1008 | return SVC_DENIED; | 1000 | return SVC_DENIED; |
1009 | |||
1010 | /* Martial context handle and token for upcall: */ | 1001 | /* Martial context handle and token for upcall: */ |
1011 | *authp = rpc_autherr_badcred; | 1002 | *authp = rpc_autherr_badcred; |
1012 | if (gc->gc_proc == RPC_GSS_PROC_INIT && gc->gc_ctx.len != 0) | 1003 | if (gc->gc_proc == RPC_GSS_PROC_INIT && gc->gc_ctx.len != 0) |
1013 | return SVC_DENIED; | 1004 | return SVC_DENIED; |
1014 | memset(&rsikey, 0, sizeof(rsikey)); | 1005 | if (dup_netobj(in_handle, &gc->gc_ctx)) |
1015 | if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx)) | ||
1016 | return SVC_CLOSE; | 1006 | return SVC_CLOSE; |
1017 | *authp = rpc_autherr_badverf; | 1007 | *authp = rpc_autherr_badverf; |
1018 | if (svc_safe_getnetobj(argv, &tmpobj)) { | 1008 | if (svc_safe_getnetobj(argv, &tmpobj)) { |
1019 | kfree(rsikey.in_handle.data); | 1009 | kfree(in_handle->data); |
1020 | return SVC_DENIED; | 1010 | return SVC_DENIED; |
1021 | } | 1011 | } |
1022 | if (dup_netobj(&rsikey.in_token, &tmpobj)) { | 1012 | if (dup_netobj(in_token, &tmpobj)) { |
1023 | kfree(rsikey.in_handle.data); | 1013 | kfree(in_handle->data); |
1024 | return SVC_CLOSE; | 1014 | return SVC_CLOSE; |
1025 | } | 1015 | } |
1026 | 1016 | ||
1017 | return 0; | ||
1018 | } | ||
1019 | |||
1020 | static inline int | ||
1021 | gss_write_resv(struct kvec *resv, size_t size_limit, | ||
1022 | struct xdr_netobj *out_handle, struct xdr_netobj *out_token, | ||
1023 | int major_status, int minor_status) | ||
1024 | { | ||
1025 | if (resv->iov_len + 4 > size_limit) | ||
1026 | return -1; | ||
1027 | svc_putnl(resv, RPC_SUCCESS); | ||
1028 | if (svc_safe_putnetobj(resv, out_handle)) | ||
1029 | return -1; | ||
1030 | if (resv->iov_len + 3 * 4 > size_limit) | ||
1031 | return -1; | ||
1032 | svc_putnl(resv, major_status); | ||
1033 | svc_putnl(resv, minor_status); | ||
1034 | svc_putnl(resv, GSS_SEQ_WIN); | ||
1035 | if (svc_safe_putnetobj(resv, out_token)) | ||
1036 | return -1; | ||
1037 | return 0; | ||
1038 | } | ||
1039 | |||
1040 | /* | ||
1041 | * Having read the cred already and found we're in the context | ||
1042 | * initiation case, read the verifier and initiate (or check the results | ||
1043 | * of) upcalls to userspace for help with context initiation. If | ||
1044 | * the upcall results are available, write the verifier and result. | ||
1045 | * Otherwise, drop the request pending an answer to the upcall. | ||
1046 | */ | ||
1047 | static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | ||
1048 | struct rpc_gss_wire_cred *gc, __be32 *authp) | ||
1049 | { | ||
1050 | struct kvec *argv = &rqstp->rq_arg.head[0]; | ||
1051 | struct kvec *resv = &rqstp->rq_res.head[0]; | ||
1052 | struct rsi *rsip, rsikey; | ||
1053 | int ret; | ||
1054 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); | ||
1055 | |||
1056 | memset(&rsikey, 0, sizeof(rsikey)); | ||
1057 | ret = gss_read_verf(gc, argv, authp, | ||
1058 | &rsikey.in_handle, &rsikey.in_token); | ||
1059 | if (ret) | ||
1060 | return ret; | ||
1061 | |||
1027 | /* Perform upcall, or find upcall result: */ | 1062 | /* Perform upcall, or find upcall result: */ |
1028 | rsip = rsi_lookup(sn->rsi_cache, &rsikey); | 1063 | rsip = rsi_lookup(sn->rsi_cache, &rsikey); |
1029 | rsi_free(&rsikey); | 1064 | rsi_free(&rsikey); |
@@ -1035,19 +1070,12 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp, | |||
1035 | 1070 | ||
1036 | ret = SVC_CLOSE; | 1071 | ret = SVC_CLOSE; |
1037 | /* Got an answer to the upcall; use it: */ | 1072 | /* Got an answer to the upcall; use it: */ |
1038 | if (gss_write_init_verf(sn->rsc_cache, rqstp, rsip)) | 1073 | if (gss_write_init_verf(sn->rsc_cache, rqstp, |
1074 | &rsip->out_handle, &rsip->major_status)) | ||
1039 | goto out; | 1075 | goto out; |
1040 | if (resv->iov_len + 4 > PAGE_SIZE) | 1076 | if (gss_write_resv(resv, PAGE_SIZE, |
1041 | goto out; | 1077 | &rsip->out_handle, &rsip->out_token, |
1042 | svc_putnl(resv, RPC_SUCCESS); | 1078 | rsip->major_status, rsip->minor_status)) |
1043 | if (svc_safe_putnetobj(resv, &rsip->out_handle)) | ||
1044 | goto out; | ||
1045 | if (resv->iov_len + 3 * 4 > PAGE_SIZE) | ||
1046 | goto out; | ||
1047 | svc_putnl(resv, rsip->major_status); | ||
1048 | svc_putnl(resv, rsip->minor_status); | ||
1049 | svc_putnl(resv, GSS_SEQ_WIN); | ||
1050 | if (svc_safe_putnetobj(resv, &rsip->out_token)) | ||
1051 | goto out; | 1079 | goto out; |
1052 | 1080 | ||
1053 | ret = SVC_COMPLETE; | 1081 | ret = SVC_COMPLETE; |