aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-15 11:16:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-15 11:16:53 -0400
commit37ca506adc395a028cd12760eca419dd0dc14b5c (patch)
treebab6f2644ef6bda4df1518f7063852012b69f458 /net
parentb9090071a57185707c27b9d61b81bf941dbdf122 (diff)
parenta16e92edcd0a2846455a30823e1bac964e743baa (diff)
Merge branch 'nfs-server-stable' of git://linux-nfs.org/~bfields/linux
* 'nfs-server-stable' of git://linux-nfs.org/~bfields/linux: knfsd: query filesystem for NFSv4 getattr of FATTR4_MAXNAME knfsd: nfsv4 delegation recall should take reference on client knfsd: don't shutdown callbacks until nfsv4 client is freed knfsd: let nfsd manage timing out its own leases knfsd: Add source address to sunrpc svc errors knfsd: 64 bit ino support for NFS server svcgss: move init code into separate function knfsd: remove code duplication in nfsd4_setclientid() nfsd warning fix knfsd: fix callback rpc cred knfsd: move nfsv4 slab creation/destruction to module init/exit knfsd: spawn kernel thread to probe callback channel knfsd: nfs4 name->id mapping not correctly parsing negative downcall knfsd: demote some printk()s to dprintk()s knfsd: cleanup of nfsd4 cmp_* functions knfsd: delete code made redundant by map_new_errors nfsd: fix horrible indentation in nfsd_setattr nfsd: remove unused cache_for_each macro nfsd: tone down inaccurate dprintk
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c144
-rw-r--r--net/sunrpc/svc.c40
2 files changed, 107 insertions, 77 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 7da7050f06c3..73940df6c460 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -631,7 +631,8 @@ svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)
631 return 0; 631 return 0;
632} 632}
633 633
634/* Verify the checksum on the header and return SVC_OK on success. 634/*
635 * Verify the checksum on the header and return SVC_OK on success.
635 * Otherwise, return SVC_DROP (in the case of a bad sequence number) 636 * Otherwise, return SVC_DROP (in the case of a bad sequence number)
636 * or return SVC_DENIED and indicate error in authp. 637 * or return SVC_DENIED and indicate error in authp.
637 */ 638 */
@@ -961,6 +962,78 @@ gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
961} 962}
962 963
963/* 964/*
965 * Having read the cred already and found we're in the context
966 * initiation case, read the verifier and initiate (or check the results
967 * of) upcalls to userspace for help with context initiation. If
968 * the upcall results are available, write the verifier and result.
969 * Otherwise, drop the request pending an answer to the upcall.
970 */
971static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
972 struct rpc_gss_wire_cred *gc, __be32 *authp)
973{
974 struct kvec *argv = &rqstp->rq_arg.head[0];
975 struct kvec *resv = &rqstp->rq_res.head[0];
976 struct xdr_netobj tmpobj;
977 struct rsi *rsip, rsikey;
978
979 /* Read the verifier; should be NULL: */
980 *authp = rpc_autherr_badverf;
981 if (argv->iov_len < 2 * 4)
982 return SVC_DENIED;
983 if (svc_getnl(argv) != RPC_AUTH_NULL)
984 return SVC_DENIED;
985 if (svc_getnl(argv) != 0)
986 return SVC_DENIED;
987
988 /* Martial context handle and token for upcall: */
989 *authp = rpc_autherr_badcred;
990 if (gc->gc_proc == RPC_GSS_PROC_INIT && gc->gc_ctx.len != 0)
991 return SVC_DENIED;
992 memset(&rsikey, 0, sizeof(rsikey));
993 if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx))
994 return SVC_DROP;
995 *authp = rpc_autherr_badverf;
996 if (svc_safe_getnetobj(argv, &tmpobj)) {
997 kfree(rsikey.in_handle.data);
998 return SVC_DENIED;
999 }
1000 if (dup_netobj(&rsikey.in_token, &tmpobj)) {
1001 kfree(rsikey.in_handle.data);
1002 return SVC_DROP;
1003 }
1004
1005 /* Perform upcall, or find upcall result: */
1006 rsip = rsi_lookup(&rsikey);
1007 rsi_free(&rsikey);
1008 if (!rsip)
1009 return SVC_DROP;
1010 switch (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
1011 case -EAGAIN:
1012 case -ETIMEDOUT:
1013 case -ENOENT:
1014 /* No upcall result: */
1015 return SVC_DROP;
1016 case 0:
1017 /* Got an answer to the upcall; use it: */
1018 if (gss_write_init_verf(rqstp, rsip))
1019 return SVC_DROP;
1020 if (resv->iov_len + 4 > PAGE_SIZE)
1021 return SVC_DROP;
1022 svc_putnl(resv, RPC_SUCCESS);
1023 if (svc_safe_putnetobj(resv, &rsip->out_handle))
1024 return SVC_DROP;
1025 if (resv->iov_len + 3 * 4 > PAGE_SIZE)
1026 return SVC_DROP;
1027 svc_putnl(resv, rsip->major_status);
1028 svc_putnl(resv, rsip->minor_status);
1029 svc_putnl(resv, GSS_SEQ_WIN);
1030 if (svc_safe_putnetobj(resv, &rsip->out_token))
1031 return SVC_DROP;
1032 }
1033 return SVC_COMPLETE;
1034}
1035
1036/*
964 * Accept an rpcsec packet. 1037 * Accept an rpcsec packet.
965 * If context establishment, punt to user space 1038 * If context establishment, punt to user space
966 * If data exchange, verify/decrypt 1039 * If data exchange, verify/decrypt
@@ -974,11 +1047,9 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
974 struct kvec *argv = &rqstp->rq_arg.head[0]; 1047 struct kvec *argv = &rqstp->rq_arg.head[0];
975 struct kvec *resv = &rqstp->rq_res.head[0]; 1048 struct kvec *resv = &rqstp->rq_res.head[0];
976 u32 crlen; 1049 u32 crlen;
977 struct xdr_netobj tmpobj;
978 struct gss_svc_data *svcdata = rqstp->rq_auth_data; 1050 struct gss_svc_data *svcdata = rqstp->rq_auth_data;
979 struct rpc_gss_wire_cred *gc; 1051 struct rpc_gss_wire_cred *gc;
980 struct rsc *rsci = NULL; 1052 struct rsc *rsci = NULL;
981 struct rsi *rsip, rsikey;
982 __be32 *rpcstart; 1053 __be32 *rpcstart;
983 __be32 *reject_stat = resv->iov_base + resv->iov_len; 1054 __be32 *reject_stat = resv->iov_base + resv->iov_len;
984 int ret; 1055 int ret;
@@ -1023,30 +1094,14 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1023 if ((gc->gc_proc != RPC_GSS_PROC_DATA) && (rqstp->rq_proc != 0)) 1094 if ((gc->gc_proc != RPC_GSS_PROC_DATA) && (rqstp->rq_proc != 0))
1024 goto auth_err; 1095 goto auth_err;
1025 1096
1026 /*
1027 * We've successfully parsed the credential. Let's check out the
1028 * verifier. An AUTH_NULL verifier is allowed (and required) for
1029 * INIT and CONTINUE_INIT requests. AUTH_RPCSEC_GSS is required for
1030 * PROC_DATA and PROC_DESTROY.
1031 *
1032 * AUTH_NULL verifier is 0 (AUTH_NULL), 0 (length).
1033 * AUTH_RPCSEC_GSS verifier is:
1034 * 6 (AUTH_RPCSEC_GSS), length, checksum.
1035 * checksum is calculated over rpcheader from xid up to here.
1036 */
1037 *authp = rpc_autherr_badverf; 1097 *authp = rpc_autherr_badverf;
1038 switch (gc->gc_proc) { 1098 switch (gc->gc_proc) {
1039 case RPC_GSS_PROC_INIT: 1099 case RPC_GSS_PROC_INIT:
1040 case RPC_GSS_PROC_CONTINUE_INIT: 1100 case RPC_GSS_PROC_CONTINUE_INIT:
1041 if (argv->iov_len < 2 * 4) 1101 return svcauth_gss_handle_init(rqstp, gc, authp);
1042 goto auth_err;
1043 if (svc_getnl(argv) != RPC_AUTH_NULL)
1044 goto auth_err;
1045 if (svc_getnl(argv) != 0)
1046 goto auth_err;
1047 break;
1048 case RPC_GSS_PROC_DATA: 1102 case RPC_GSS_PROC_DATA:
1049 case RPC_GSS_PROC_DESTROY: 1103 case RPC_GSS_PROC_DESTROY:
1104 /* Look up the context, and check the verifier: */
1050 *authp = rpcsec_gsserr_credproblem; 1105 *authp = rpcsec_gsserr_credproblem;
1051 rsci = gss_svc_searchbyctx(&gc->gc_ctx); 1106 rsci = gss_svc_searchbyctx(&gc->gc_ctx);
1052 if (!rsci) 1107 if (!rsci)
@@ -1067,51 +1122,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1067 1122
1068 /* now act upon the command: */ 1123 /* now act upon the command: */
1069 switch (gc->gc_proc) { 1124 switch (gc->gc_proc) {
1070 case RPC_GSS_PROC_INIT:
1071 case RPC_GSS_PROC_CONTINUE_INIT:
1072 *authp = rpc_autherr_badcred;
1073 if (gc->gc_proc == RPC_GSS_PROC_INIT && gc->gc_ctx.len != 0)
1074 goto auth_err;
1075 memset(&rsikey, 0, sizeof(rsikey));
1076 if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx))
1077 goto drop;
1078 *authp = rpc_autherr_badverf;
1079 if (svc_safe_getnetobj(argv, &tmpobj)) {
1080 kfree(rsikey.in_handle.data);
1081 goto auth_err;
1082 }
1083 if (dup_netobj(&rsikey.in_token, &tmpobj)) {
1084 kfree(rsikey.in_handle.data);
1085 goto drop;
1086 }
1087
1088 rsip = rsi_lookup(&rsikey);
1089 rsi_free(&rsikey);
1090 if (!rsip) {
1091 goto drop;
1092 }
1093 switch(cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
1094 case -EAGAIN:
1095 case -ETIMEDOUT:
1096 case -ENOENT:
1097 goto drop;
1098 case 0:
1099 if (gss_write_init_verf(rqstp, rsip))
1100 goto drop;
1101 if (resv->iov_len + 4 > PAGE_SIZE)
1102 goto drop;
1103 svc_putnl(resv, RPC_SUCCESS);
1104 if (svc_safe_putnetobj(resv, &rsip->out_handle))
1105 goto drop;
1106 if (resv->iov_len + 3 * 4 > PAGE_SIZE)
1107 goto drop;
1108 svc_putnl(resv, rsip->major_status);
1109 svc_putnl(resv, rsip->minor_status);
1110 svc_putnl(resv, GSS_SEQ_WIN);
1111 if (svc_safe_putnetobj(resv, &rsip->out_token))
1112 goto drop;
1113 }
1114 goto complete;
1115 case RPC_GSS_PROC_DESTROY: 1125 case RPC_GSS_PROC_DESTROY:
1116 if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) 1126 if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq))
1117 goto auth_err; 1127 goto auth_err;
@@ -1158,7 +1168,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1158 goto out; 1168 goto out;
1159 } 1169 }
1160auth_err: 1170auth_err:
1161 /* Restore write pointer to original value: */ 1171 /* Restore write pointer to its original value: */
1162 xdr_ressize_check(rqstp, reject_stat); 1172 xdr_ressize_check(rqstp, reject_stat);
1163 ret = SVC_DENIED; 1173 ret = SVC_DENIED;
1164 goto out; 1174 goto out;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 55ea6df069de..a4a6bf7deaa4 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -777,6 +777,30 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
777} 777}
778 778
779/* 779/*
780 * Printk the given error with the address of the client that caused it.
781 */
782static int
783__attribute__ ((format (printf, 2, 3)))
784svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
785{
786 va_list args;
787 int r;
788 char buf[RPC_MAX_ADDRBUFLEN];
789
790 if (!net_ratelimit())
791 return 0;
792
793 printk(KERN_WARNING "svc: %s: ",
794 svc_print_addr(rqstp, buf, sizeof(buf)));
795
796 va_start(args, fmt);
797 r = vprintk(fmt, args);
798 va_end(args);
799
800 return r;
801}
802
803/*
780 * Process the RPC request. 804 * Process the RPC request.
781 */ 805 */
782int 806int
@@ -963,14 +987,13 @@ svc_process(struct svc_rqst *rqstp)
963 return 0; 987 return 0;
964 988
965err_short_len: 989err_short_len:
966 if (net_ratelimit()) 990 svc_printk(rqstp, "short len %Zd, dropping request\n",
967 printk("svc: short len %Zd, dropping request\n", argv->iov_len); 991 argv->iov_len);
968 992
969 goto dropit; /* drop request */ 993 goto dropit; /* drop request */
970 994
971err_bad_dir: 995err_bad_dir:
972 if (net_ratelimit()) 996 svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
973 printk("svc: bad direction %d, dropping request\n", dir);
974 997
975 serv->sv_stats->rpcbadfmt++; 998 serv->sv_stats->rpcbadfmt++;
976 goto dropit; /* drop request */ 999 goto dropit; /* drop request */
@@ -1000,8 +1023,7 @@ err_bad_prog:
1000 goto sendit; 1023 goto sendit;
1001 1024
1002err_bad_vers: 1025err_bad_vers:
1003 if (net_ratelimit()) 1026 svc_printk(rqstp, "unknown version (%d for prog %d, %s)\n",
1004 printk("svc: unknown version (%d for prog %d, %s)\n",
1005 vers, prog, progp->pg_name); 1027 vers, prog, progp->pg_name);
1006 1028
1007 serv->sv_stats->rpcbadfmt++; 1029 serv->sv_stats->rpcbadfmt++;
@@ -1011,16 +1033,14 @@ err_bad_vers:
1011 goto sendit; 1033 goto sendit;
1012 1034
1013err_bad_proc: 1035err_bad_proc:
1014 if (net_ratelimit()) 1036 svc_printk(rqstp, "unknown procedure (%d)\n", proc);
1015 printk("svc: unknown procedure (%d)\n", proc);
1016 1037
1017 serv->sv_stats->rpcbadfmt++; 1038 serv->sv_stats->rpcbadfmt++;
1018 svc_putnl(resv, RPC_PROC_UNAVAIL); 1039 svc_putnl(resv, RPC_PROC_UNAVAIL);
1019 goto sendit; 1040 goto sendit;
1020 1041
1021err_garbage: 1042err_garbage:
1022 if (net_ratelimit()) 1043 svc_printk(rqstp, "failed to decode args\n");
1023 printk("svc: failed to decode args\n");
1024 1044
1025 rpc_stat = rpc_garbage_args; 1045 rpc_stat = rpc_garbage_args;
1026err_bad: 1046err_bad: