aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/export.c15
-rw-r--r--fs/nfsd/nfs4idmap.c13
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/linux/sunrpc/svcauth.h1
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c21
-rw-r--r--net/sunrpc/svcauth_unix.c4
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 *
1237rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt, 1237rqst_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
1244struct svc_export * 1246struct svc_export *
1245rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) 1247rqst_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
1251struct svc_export * 1255struct svc_export *
1252rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt, 1256rqst_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
590static char *
591rqst_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
590static int 599static int
591idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, 600idmap_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);
127extern int auth_unix_forget_old(struct auth_domain *dom); 127extern int auth_unix_forget_old(struct auth_domain *dom);
128extern void svcauth_unix_purge(void); 128extern void svcauth_unix_purge(void);
129extern void svcauth_unix_info_release(void *); 129extern void svcauth_unix_info_release(void *);
130extern int svcauth_unix_set_client(struct svc_rqst *rqstp);
130 131
131static inline unsigned long hash_str(char *name, int bits) 132static 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
641static int 641int
642svcauth_unix_set_client(struct svc_rqst *rqstp) 642svcauth_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
676EXPORT_SYMBOL(svcauth_unix_set_client);
677
676static int 678static int
677svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) 679svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
678{ 680{