aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-07-17 07:04:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:07 -0400
commit3ab4d8b1215d61736e2a9a26bea7cc2e6b029e3d (patch)
tree6b256e44c4ed5295dfd55eef8641093b91692559
parent0989a7889695831e49e2c53c1884f52645516a90 (diff)
knfsd: nfsd: set rq_client to ip-address-determined-domain
We want it to be possible for users to restrict exports both by IP address and by pseudoflavor. The pseudoflavor information has previously been passed using special auth_domains stored in the rq_client field. After the preceding patch that stored the pseudoflavor in rq_pflavor, that's now superfluous; so now we use rq_client for the ip information, as auth_null and auth_unix do. However, we keep around the special auth_domain in the rq_gssclient field for backwards compatibility purposes, so we can still do upcalls using the old "gss/pseudoflavor" auth_domain if upcalls using the unix domain to give us an appropriate export. This allows us to continue supporting old mountd. In fact, for this first patch, we always use the "gss/pseudoflavor" auth_domain (and only it) if it is available; thus rq_client is ignored in the auth_gss case, and this patch on its own makes no change in behavior; that will be left to later patches. Note on idmap: I'm almost tempted to just replace the auth_domain in the idmap upcall by a dummy value--no version of idmapd has ever used it, and it's unlikely anyone really wants to perform idmapping differently depending on the where the client is (they may want to perform *credential* mapping differently, but that's a different matter--the idmapper just handles id's used in getattr and setattr). But I'm updating the idmapd code anyway, just out of general backwards-compatibility paranoia. Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-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{