Browse Source

rpc: pass target name down to rpc level on callbacks

The rpc client needs to know the principal that the setclientid was done
as, so it can tell gssd who to authenticate to.

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>
Olga Kornievskaia 16 years ago
parent
commit
608207e888
3 changed files with 24 additions and 0 deletions
  1. 6 0
      fs/nfsd/nfs4callback.c
  2. 2 0
      include/linux/sunrpc/clnt.h
  3. 16 0
      net/sunrpc/clnt.c

+ 6 - 0
fs/nfsd/nfs4callback.c

@@ -384,6 +384,7 @@ static int do_probe_callback(void *data)
 		.version	= nfs_cb_version[1]->number,
 		.version	= nfs_cb_version[1]->number,
 		.authflavor	= RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
 		.authflavor	= RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
 		.flags		= (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
 		.flags		= (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
+		.client_name    = clp->cl_principal,
 	};
 	};
 	struct rpc_message msg = {
 	struct rpc_message msg = {
 		.rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
 		.rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
@@ -392,6 +393,11 @@ static int do_probe_callback(void *data)
 	struct rpc_clnt *client;
 	struct rpc_clnt *client;
 	int status;
 	int status;
 
 
+	if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) {
+		status = nfserr_cb_path_down;
+		goto out_err;
+	}
+
 	/* Initialize address */
 	/* Initialize address */
 	memset(&addr, 0, sizeof(addr));
 	memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
 	addr.sin_family = AF_INET;

+ 2 - 0
include/linux/sunrpc/clnt.h

@@ -58,6 +58,7 @@ struct rpc_clnt {
 	struct rpc_timeout	cl_timeout_default;
 	struct rpc_timeout	cl_timeout_default;
 	struct rpc_program *	cl_program;
 	struct rpc_program *	cl_program;
 	char			cl_inline_name[32];
 	char			cl_inline_name[32];
+	char			*cl_principal;	/* target to authenticate to */
 };
 };
 
 
 /*
 /*
@@ -108,6 +109,7 @@ struct rpc_create_args {
 	u32			version;
 	u32			version;
 	rpc_authflavor_t	authflavor;
 	rpc_authflavor_t	authflavor;
 	unsigned long		flags;
 	unsigned long		flags;
+	char			*client_name;
 };
 };
 
 
 /* Values for "flags" field */
 /* Values for "flags" field */

+ 16 - 0
net/sunrpc/clnt.c

@@ -197,6 +197,12 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
 
 
 	clnt->cl_rtt = &clnt->cl_rtt_default;
 	clnt->cl_rtt = &clnt->cl_rtt_default;
 	rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
 	rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
+	clnt->cl_principal = NULL;
+	if (args->client_name) {
+		clnt->cl_principal = kstrdup(args->client_name, GFP_KERNEL);
+		if (!clnt->cl_principal)
+			goto out_no_principal;
+	}
 
 
 	kref_init(&clnt->cl_kref);
 	kref_init(&clnt->cl_kref);
 
 
@@ -226,6 +232,8 @@ out_no_auth:
 		rpc_put_mount();
 		rpc_put_mount();
 	}
 	}
 out_no_path:
 out_no_path:
+	kfree(clnt->cl_principal);
+out_no_principal:
 	rpc_free_iostats(clnt->cl_metrics);
 	rpc_free_iostats(clnt->cl_metrics);
 out_no_stats:
 out_no_stats:
 	if (clnt->cl_server != clnt->cl_inline_name)
 	if (clnt->cl_server != clnt->cl_inline_name)
@@ -354,6 +362,11 @@ rpc_clone_client(struct rpc_clnt *clnt)
 	new->cl_metrics = rpc_alloc_iostats(clnt);
 	new->cl_metrics = rpc_alloc_iostats(clnt);
 	if (new->cl_metrics == NULL)
 	if (new->cl_metrics == NULL)
 		goto out_no_stats;
 		goto out_no_stats;
+	if (clnt->cl_principal) {
+		new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL);
+		if (new->cl_principal == NULL)
+			goto out_no_principal;
+	}
 	kref_init(&new->cl_kref);
 	kref_init(&new->cl_kref);
 	err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
 	err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
 	if (err != 0)
 	if (err != 0)
@@ -366,6 +379,8 @@ rpc_clone_client(struct rpc_clnt *clnt)
 	rpciod_up();
 	rpciod_up();
 	return new;
 	return new;
 out_no_path:
 out_no_path:
+	kfree(new->cl_principal);
+out_no_principal:
 	rpc_free_iostats(new->cl_metrics);
 	rpc_free_iostats(new->cl_metrics);
 out_no_stats:
 out_no_stats:
 	kfree(new);
 	kfree(new);
@@ -417,6 +432,7 @@ rpc_free_client(struct kref *kref)
 out_free:
 out_free:
 	rpc_unregister_client(clnt);
 	rpc_unregister_client(clnt);
 	rpc_free_iostats(clnt->cl_metrics);
 	rpc_free_iostats(clnt->cl_metrics);
+	kfree(clnt->cl_principal);
 	clnt->cl_metrics = NULL;
 	clnt->cl_metrics = NULL;
 	xprt_put(clnt->cl_xprt);
 	xprt_put(clnt->cl_xprt);
 	rpciod_down();
 	rpciod_down();