aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlga Kornievskaia <aglo@citi.umich.edu>2008-12-23 16:17:15 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-23 16:17:15 -0500
commit68e76ad0baf8f5d5060377c2423ee6eed5c63057 (patch)
treebaab3e30cc3b50bc49a553ee884885189ce85a8e
parent34769fc488b463cb753fc632f8f5ba56c918b7cb (diff)
nfsd: pass client principal name in rsc downcall
Two principals are involved in krb5 authentication: the target, who we authenticate *to* (normally the name of the server, like nfs/server.citi.umich.edu@CITI.UMICH.EDU), and the source, we we authenticate *as* (normally a user, like bfields@UMICH.EDU) In the case of NFSv4 callbacks, the target of the callback should be the source of the client's setclientid call, and the source should be the nfs server's own principal. Therefore we allow svcgssd to pass down the name of the principal that just authenticated, so that on setclientid we can store that principal name with the new client, to be used later on callbacks. Signed-off-by: Olga Kornievskaia <aglo@citi.umich.edu> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfsd/nfs4state.c11
-rw-r--r--include/linux/nfsd/state.h1
-rw-r--r--include/linux/sunrpc/svcauth_gss.h1
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c23
4 files changed, 36 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 1a052ac2bde9..f3b9a8d064f3 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -54,6 +54,7 @@
54#include <linux/mutex.h> 54#include <linux/mutex.h>
55#include <linux/lockd/bind.h> 55#include <linux/lockd/bind.h>
56#include <linux/module.h> 56#include <linux/module.h>
57#include <linux/sunrpc/svcauth_gss.h>
57 58
58#define NFSDDBG_FACILITY NFSDDBG_PROC 59#define NFSDDBG_FACILITY NFSDDBG_PROC
59 60
@@ -377,6 +378,7 @@ free_client(struct nfs4_client *clp)
377 shutdown_callback_client(clp); 378 shutdown_callback_client(clp);
378 if (clp->cl_cred.cr_group_info) 379 if (clp->cl_cred.cr_group_info)
379 put_group_info(clp->cl_cred.cr_group_info); 380 put_group_info(clp->cl_cred.cr_group_info);
381 kfree(clp->cl_principal);
380 kfree(clp->cl_name.data); 382 kfree(clp->cl_name.data);
381 kfree(clp); 383 kfree(clp);
382} 384}
@@ -696,6 +698,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
696 unsigned int strhashval; 698 unsigned int strhashval;
697 struct nfs4_client *conf, *unconf, *new; 699 struct nfs4_client *conf, *unconf, *new;
698 __be32 status; 700 __be32 status;
701 char *princ;
699 char dname[HEXDIR_LEN]; 702 char dname[HEXDIR_LEN];
700 703
701 if (!check_name(clname)) 704 if (!check_name(clname))
@@ -783,6 +786,14 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
783 } 786 }
784 copy_verf(new, &clverifier); 787 copy_verf(new, &clverifier);
785 new->cl_addr = sin->sin_addr.s_addr; 788 new->cl_addr = sin->sin_addr.s_addr;
789 princ = svc_gss_principal(rqstp);
790 if (princ) {
791 new->cl_principal = kstrdup(princ, GFP_KERNEL);
792 if (new->cl_principal == NULL) {
793 free_client(new);
794 goto out;
795 }
796 }
786 copy_cred(&new->cl_cred, &rqstp->rq_cred); 797 copy_cred(&new->cl_cred, &rqstp->rq_cred);
787 gen_confirm(new); 798 gen_confirm(new);
788 gen_callback(new, setclid); 799 gen_callback(new, setclid);
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index d0fe2e378452..ce7cbf4b7c93 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -124,6 +124,7 @@ struct nfs4_client {
124 nfs4_verifier cl_verifier; /* generated by client */ 124 nfs4_verifier cl_verifier; /* generated by client */
125 time_t cl_time; /* time of last lease renewal */ 125 time_t cl_time; /* time of last lease renewal */
126 __be32 cl_addr; /* client ipaddress */ 126 __be32 cl_addr; /* client ipaddress */
127 char *cl_principal; /* setclientid principal name */
127 struct svc_cred cl_cred; /* setclientid principal */ 128 struct svc_cred cl_cred; /* setclientid principal */
128 clientid_t cl_clientid; /* generated by server */ 129 clientid_t cl_clientid; /* generated by server */
129 nfs4_verifier cl_confirm; /* generated by server */ 130 nfs4_verifier cl_confirm; /* generated by server */
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
index c9165d9771a8..ca7d725861fc 100644
--- a/include/linux/sunrpc/svcauth_gss.h
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -20,6 +20,7 @@ int gss_svc_init(void);
20void gss_svc_shutdown(void); 20void gss_svc_shutdown(void);
21int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name); 21int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
22u32 svcauth_gss_flavor(struct auth_domain *dom); 22u32 svcauth_gss_flavor(struct auth_domain *dom);
23char *svc_gss_principal(struct svc_rqst *);
23 24
24#endif /* __KERNEL__ */ 25#endif /* __KERNEL__ */
25#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */ 26#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 12803da95dc4..e9baa6ebb1dd 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -332,6 +332,7 @@ struct rsc {
332 struct svc_cred cred; 332 struct svc_cred cred;
333 struct gss_svc_seq_data seqdata; 333 struct gss_svc_seq_data seqdata;
334 struct gss_ctx *mechctx; 334 struct gss_ctx *mechctx;
335 char *client_name;
335}; 336};
336 337
337static struct cache_head *rsc_table[RSC_HASHMAX]; 338static struct cache_head *rsc_table[RSC_HASHMAX];
@@ -346,6 +347,7 @@ static void rsc_free(struct rsc *rsci)
346 gss_delete_sec_context(&rsci->mechctx); 347 gss_delete_sec_context(&rsci->mechctx);
347 if (rsci->cred.cr_group_info) 348 if (rsci->cred.cr_group_info)
348 put_group_info(rsci->cred.cr_group_info); 349 put_group_info(rsci->cred.cr_group_info);
350 kfree(rsci->client_name);
349} 351}
350 352
351static void rsc_put(struct kref *ref) 353static void rsc_put(struct kref *ref)
@@ -383,6 +385,7 @@ rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
383 tmp->handle.data = NULL; 385 tmp->handle.data = NULL;
384 new->mechctx = NULL; 386 new->mechctx = NULL;
385 new->cred.cr_group_info = NULL; 387 new->cred.cr_group_info = NULL;
388 new->client_name = NULL;
386} 389}
387 390
388static void 391static void
@@ -397,6 +400,8 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
397 spin_lock_init(&new->seqdata.sd_lock); 400 spin_lock_init(&new->seqdata.sd_lock);
398 new->cred = tmp->cred; 401 new->cred = tmp->cred;
399 tmp->cred.cr_group_info = NULL; 402 tmp->cred.cr_group_info = NULL;
403 new->client_name = tmp->client_name;
404 tmp->client_name = NULL;
400} 405}
401 406
402static struct cache_head * 407static struct cache_head *
@@ -486,6 +491,15 @@ static int rsc_parse(struct cache_detail *cd,
486 status = gss_import_sec_context(buf, len, gm, &rsci.mechctx); 491 status = gss_import_sec_context(buf, len, gm, &rsci.mechctx);
487 if (status) 492 if (status)
488 goto out; 493 goto out;
494
495 /* get client name */
496 len = qword_get(&mesg, buf, mlen);
497 if (len > 0) {
498 rsci.client_name = kstrdup(buf, GFP_KERNEL);
499 if (!rsci.client_name)
500 goto out;
501 }
502
489 } 503 }
490 rsci.h.expiry_time = expiry; 504 rsci.h.expiry_time = expiry;
491 rscp = rsc_update(&rsci, rscp); 505 rscp = rsc_update(&rsci, rscp);
@@ -913,6 +927,15 @@ struct gss_svc_data {
913 struct rsc *rsci; 927 struct rsc *rsci;
914}; 928};
915 929
930char *svc_gss_principal(struct svc_rqst *rqstp)
931{
932 struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data;
933
934 if (gd && gd->rsci)
935 return gd->rsci->client_name;
936 return NULL;
937}
938
916static int 939static int
917svcauth_gss_set_client(struct svc_rqst *rqstp) 940svcauth_gss_set_client(struct svc_rqst *rqstp)
918{ 941{