diff options
-rw-r--r-- | fs/nfsd/export.c | 15 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 13 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 2 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 1 | ||||
-rw-r--r-- | include/linux/sunrpc/svcauth.h | 1 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 21 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 4 |
7 files changed, 45 insertions, 12 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 9b569af695ab..ac225a79376c 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1237,21 +1237,28 @@ struct svc_export * | |||
1237 | rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt, | 1237 | rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt, |
1238 | struct dentry *dentry) | 1238 | struct dentry *dentry) |
1239 | { | 1239 | { |
1240 | return exp_get_by_name(rqstp->rq_client, mnt, dentry, | 1240 | struct auth_domain *clp; |
1241 | &rqstp->rq_chandle); | 1241 | |
1242 | clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client; | ||
1243 | return exp_get_by_name(clp, mnt, dentry, &rqstp->rq_chandle); | ||
1242 | } | 1244 | } |
1243 | 1245 | ||
1244 | struct svc_export * | 1246 | struct svc_export * |
1245 | rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) | 1247 | rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) |
1246 | { | 1248 | { |
1247 | return exp_find(rqstp->rq_client, fsid_type, fsidv, | 1249 | struct auth_domain *clp; |
1248 | &rqstp->rq_chandle); | 1250 | |
1251 | clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client; | ||
1252 | return exp_find(clp, fsid_type, fsidv, &rqstp->rq_chandle); | ||
1249 | } | 1253 | } |
1250 | 1254 | ||
1251 | struct svc_export * | 1255 | struct svc_export * |
1252 | rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, | 1256 | rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, |
1253 | struct dentry *dentry) | 1257 | struct dentry *dentry) |
1254 | { | 1258 | { |
1259 | struct auth_domain *clp; | ||
1260 | |||
1261 | clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client; | ||
1255 | return exp_parent(rqstp->rq_client, mnt, dentry, &rqstp->rq_chandle); | 1262 | return exp_parent(rqstp->rq_client, mnt, dentry, &rqstp->rq_chandle); |
1256 | } | 1263 | } |
1257 | 1264 | ||
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 45aa21ce6784..2cf9a9a2d89c 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -587,6 +587,15 @@ idmap_lookup(struct svc_rqst *rqstp, | |||
587 | return ret; | 587 | return ret; |
588 | } | 588 | } |
589 | 589 | ||
590 | static char * | ||
591 | rqst_authname(struct svc_rqst *rqstp) | ||
592 | { | ||
593 | struct auth_domain *clp; | ||
594 | |||
595 | clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client; | ||
596 | return clp->name; | ||
597 | } | ||
598 | |||
590 | static int | 599 | static int |
591 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, | 600 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, |
592 | uid_t *id) | 601 | uid_t *id) |
@@ -600,7 +609,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen | |||
600 | return -EINVAL; | 609 | return -EINVAL; |
601 | memcpy(key.name, name, namelen); | 610 | memcpy(key.name, name, namelen); |
602 | key.name[namelen] = '\0'; | 611 | key.name[namelen] = '\0'; |
603 | strlcpy(key.authname, rqstp->rq_client->name, sizeof(key.authname)); | 612 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); |
604 | ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); | 613 | ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); |
605 | if (ret == -ENOENT) | 614 | if (ret == -ENOENT) |
606 | ret = -ESRCH; /* nfserr_badname */ | 615 | ret = -ESRCH; /* nfserr_badname */ |
@@ -620,7 +629,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
620 | }; | 629 | }; |
621 | int ret; | 630 | int ret; |
622 | 631 | ||
623 | strlcpy(key.authname, rqstp->rq_client->name, sizeof(key.authname)); | 632 | strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); |
624 | ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item); | 633 | ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item); |
625 | if (ret == -ENOENT) | 634 | if (ret == -ENOENT) |
626 | return sprintf(name, "%u", id); | 635 | return sprintf(name, "%u", id); |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 180e068ea064..22cb5be79ad0 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -120,8 +120,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
120 | int data_left = fh->fh_size/4; | 120 | int data_left = fh->fh_size/4; |
121 | 121 | ||
122 | error = nfserr_stale; | 122 | error = nfserr_stale; |
123 | if (rqstp->rq_client == NULL) | ||
124 | goto out; | ||
125 | if (rqstp->rq_vers > 2) | 123 | if (rqstp->rq_vers > 2) |
126 | error = nfserr_badhandle; | 124 | error = nfserr_badhandle; |
127 | if (rqstp->rq_vers == 4 && fh->fh_size == 0) | 125 | if (rqstp->rq_vers == 4 && fh->fh_size == 0) |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 705a90aa345e..8531a70da73d 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -249,6 +249,7 @@ struct svc_rqst { | |||
249 | */ | 249 | */ |
250 | /* Catering to nfsd */ | 250 | /* Catering to nfsd */ |
251 | struct auth_domain * rq_client; /* RPC peer info */ | 251 | struct auth_domain * rq_client; /* RPC peer info */ |
252 | struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ | ||
252 | struct svc_cacherep * rq_cacherep; /* cache info */ | 253 | struct svc_cacherep * rq_cacherep; /* cache info */ |
253 | struct knfsd_fh * rq_reffh; /* Referrence filehandle, used to | 254 | struct knfsd_fh * rq_reffh; /* Referrence filehandle, used to |
254 | * determine what device number | 255 | * determine what device number |
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index de92619b0826..22e1ef8e200e 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h | |||
@@ -127,6 +127,7 @@ extern struct auth_domain *auth_unix_lookup(struct in_addr addr); | |||
127 | extern int auth_unix_forget_old(struct auth_domain *dom); | 127 | extern int auth_unix_forget_old(struct auth_domain *dom); |
128 | extern void svcauth_unix_purge(void); | 128 | extern void svcauth_unix_purge(void); |
129 | extern void svcauth_unix_info_release(void *); | 129 | extern void svcauth_unix_info_release(void *); |
130 | extern int svcauth_unix_set_client(struct svc_rqst *rqstp); | ||
130 | 131 | ||
131 | static inline unsigned long hash_str(char *name, int bits) | 132 | static inline unsigned long hash_str(char *name, int bits) |
132 | { | 133 | { |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 7a3e1758bea1..e4b3de08b040 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -913,10 +913,23 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) | |||
913 | struct gss_svc_data *svcdata = rqstp->rq_auth_data; | 913 | struct gss_svc_data *svcdata = rqstp->rq_auth_data; |
914 | struct rsc *rsci = svcdata->rsci; | 914 | struct rsc *rsci = svcdata->rsci; |
915 | struct rpc_gss_wire_cred *gc = &svcdata->clcred; | 915 | struct rpc_gss_wire_cred *gc = &svcdata->clcred; |
916 | int stat; | ||
916 | 917 | ||
917 | rqstp->rq_client = find_gss_auth_domain(rsci->mechctx, gc->gc_svc); | 918 | /* |
918 | if (rqstp->rq_client == NULL) | 919 | * A gss export can be specified either by: |
920 | * export *(sec=krb5,rw) | ||
921 | * or by | ||
922 | * export gss/krb5(rw) | ||
923 | * The latter is deprecated; but for backwards compatibility reasons | ||
924 | * the nfsd code will still fall back on trying it if the former | ||
925 | * doesn't work; so we try to make both available to nfsd, below. | ||
926 | */ | ||
927 | rqstp->rq_gssclient = find_gss_auth_domain(rsci->mechctx, gc->gc_svc); | ||
928 | if (rqstp->rq_gssclient == NULL) | ||
919 | return SVC_DENIED; | 929 | return SVC_DENIED; |
930 | stat = svcauth_unix_set_client(rqstp); | ||
931 | if (stat == SVC_DROP) | ||
932 | return stat; | ||
920 | return SVC_OK; | 933 | return SVC_OK; |
921 | } | 934 | } |
922 | 935 | ||
@@ -1088,7 +1101,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
1088 | svc_putnl(resv, GSS_SEQ_WIN); | 1101 | svc_putnl(resv, GSS_SEQ_WIN); |
1089 | if (svc_safe_putnetobj(resv, &rsip->out_token)) | 1102 | if (svc_safe_putnetobj(resv, &rsip->out_token)) |
1090 | goto drop; | 1103 | goto drop; |
1091 | rqstp->rq_client = NULL; | ||
1092 | } | 1104 | } |
1093 | goto complete; | 1105 | goto complete; |
1094 | case RPC_GSS_PROC_DESTROY: | 1106 | case RPC_GSS_PROC_DESTROY: |
@@ -1319,6 +1331,9 @@ out_err: | |||
1319 | if (rqstp->rq_client) | 1331 | if (rqstp->rq_client) |
1320 | auth_domain_put(rqstp->rq_client); | 1332 | auth_domain_put(rqstp->rq_client); |
1321 | rqstp->rq_client = NULL; | 1333 | rqstp->rq_client = NULL; |
1334 | if (rqstp->rq_gssclient) | ||
1335 | auth_domain_put(rqstp->rq_gssclient); | ||
1336 | rqstp->rq_gssclient = NULL; | ||
1322 | if (rqstp->rq_cred.cr_group_info) | 1337 | if (rqstp->rq_cred.cr_group_info) |
1323 | put_group_info(rqstp->rq_cred.cr_group_info); | 1338 | put_group_info(rqstp->rq_cred.cr_group_info); |
1324 | rqstp->rq_cred.cr_group_info = NULL; | 1339 | rqstp->rq_cred.cr_group_info = NULL; |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index d9fdf2e4d242..411479411b21 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -638,7 +638,7 @@ static int unix_gid_find(uid_t uid, struct group_info **gip, | |||
638 | } | 638 | } |
639 | } | 639 | } |
640 | 640 | ||
641 | static int | 641 | int |
642 | svcauth_unix_set_client(struct svc_rqst *rqstp) | 642 | svcauth_unix_set_client(struct svc_rqst *rqstp) |
643 | { | 643 | { |
644 | struct sockaddr_in *sin = svc_addr_in(rqstp); | 644 | struct sockaddr_in *sin = svc_addr_in(rqstp); |
@@ -673,6 +673,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) | |||
673 | return SVC_OK; | 673 | return SVC_OK; |
674 | } | 674 | } |
675 | 675 | ||
676 | EXPORT_SYMBOL(svcauth_unix_set_client); | ||
677 | |||
676 | static int | 678 | static int |
677 | svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) | 679 | svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) |
678 | { | 680 | { |