Commit 19172284 authored by Trond Myklebust's avatar Trond Myklebust

RPCSEC_GSS: Switch auth_gss to use the new framework for pipefs dentries

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 6739ffb7
...@@ -71,6 +71,13 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED; ...@@ -71,6 +71,13 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
* using integrity (two 4-byte integers): */ * using integrity (two 4-byte integers): */
#define GSS_VERF_SLACK 100 #define GSS_VERF_SLACK 100
struct gss_pipe {
struct rpc_pipe_dir_object pdo;
struct rpc_pipe *pipe;
struct rpc_clnt *clnt;
const char *name;
};
struct gss_auth { struct gss_auth {
struct kref kref; struct kref kref;
struct rpc_auth rpc_auth; struct rpc_auth rpc_auth;
...@@ -84,7 +91,7 @@ struct gss_auth { ...@@ -84,7 +91,7 @@ struct gss_auth {
* mechanism (for example, "krb5") and exists for * mechanism (for example, "krb5") and exists for
* backwards-compatibility with older gssd's. * backwards-compatibility with older gssd's.
*/ */
struct rpc_pipe *pipe[2]; struct gss_pipe *gss_pipe[2];
const char *target_name; const char *target_name;
}; };
...@@ -456,7 +463,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, ...@@ -456,7 +463,7 @@ gss_alloc_msg(struct gss_auth *gss_auth,
kfree(gss_msg); kfree(gss_msg);
return ERR_PTR(vers); return ERR_PTR(vers);
} }
gss_msg->pipe = gss_auth->pipe[vers]; gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe;
INIT_LIST_HEAD(&gss_msg->list); INIT_LIST_HEAD(&gss_msg->list);
rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
init_waitqueue_head(&gss_msg->waitqueue); init_waitqueue_head(&gss_msg->waitqueue);
...@@ -791,85 +798,83 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) ...@@ -791,85 +798,83 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
} }
} }
static void gss_pipes_dentries_destroy(struct rpc_auth *auth) static void gss_pipe_dentry_destroy(struct dentry *dir,
struct rpc_pipe_dir_object *pdo)
{ {
struct gss_auth *gss_auth; struct gss_pipe *gss_pipe = pdo->pdo_data;
struct rpc_pipe *pipe = gss_pipe->pipe;
gss_auth = container_of(auth, struct gss_auth, rpc_auth); if (pipe->dentry != NULL) {
if (gss_auth->pipe[0]->dentry) { rpc_unlink(pipe->dentry);
rpc_unlink(gss_auth->pipe[0]->dentry); pipe->dentry = NULL;
gss_auth->pipe[0]->dentry = NULL;
}
if (gss_auth->pipe[1]->dentry) {
rpc_unlink(gss_auth->pipe[1]->dentry);
gss_auth->pipe[1]->dentry = NULL;
} }
} }
static int gss_pipes_dentries_create(struct rpc_auth *auth) static int gss_pipe_dentry_create(struct dentry *dir,
struct rpc_pipe_dir_object *pdo)
{ {
int err; struct gss_pipe *p = pdo->pdo_data;
struct gss_auth *gss_auth;
struct rpc_clnt *clnt;
struct dentry *dentry; struct dentry *dentry;
gss_auth = container_of(auth, struct gss_auth, rpc_auth); dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe);
clnt = gss_auth->client; if (IS_ERR(dentry))
return PTR_ERR(dentry);
p->pipe->dentry = dentry;
return 0;
}
static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = {
.create = gss_pipe_dentry_create,
.destroy = gss_pipe_dentry_destroy,
};
static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt,
const char *name,
const struct rpc_pipe_ops *upcall_ops)
{
struct net *net = rpc_net_ns(clnt);
struct gss_pipe *p;
int err = -ENOMEM;
dentry = rpc_mkpipe_dentry(clnt->cl_dentry, "gssd", p = kmalloc(sizeof(*p), GFP_KERNEL);
clnt, gss_auth->pipe[1]); if (p == NULL)
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
goto err; goto err;
p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
if (IS_ERR(p->pipe)) {
err = PTR_ERR(p->pipe);
goto err_free_gss_pipe;
} }
gss_auth->pipe[1]->dentry = dentry; p->name = name;
dentry = rpc_mkpipe_dentry(clnt->cl_dentry, gss_auth->mech->gm_name, p->clnt = clnt;
clnt, gss_auth->pipe[0]); rpc_init_pipe_dir_object(&p->pdo,
if (IS_ERR(dentry)) { &gss_pipe_dir_object_ops,
err = PTR_ERR(dentry); p);
goto err_unlink_pipe_1; err = rpc_add_pipe_dir_object(net, &clnt->cl_pipedir_objects, &p->pdo);
} if (!err)
return 0; return p;
rpc_destroy_pipe_data(p->pipe);
err_unlink_pipe_1: err_free_gss_pipe:
rpc_unlink(gss_auth->pipe[1]->dentry); kfree(p);
gss_auth->pipe[1]->dentry = NULL;
err: err:
return err; return ERR_PTR(err);
} }
static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt, static void __gss_pipe_free(struct gss_pipe *p)
struct rpc_auth *auth)
{ {
struct gss_auth *gss_auth = container_of(auth, struct gss_auth, struct rpc_clnt *clnt = p->clnt;
rpc_auth); struct net *net = rpc_net_ns(clnt);
struct net *net = gss_auth->net;
struct super_block *sb;
sb = rpc_get_sb_net(net); rpc_remove_pipe_dir_object(net,
if (sb) { &clnt->cl_pipedir_objects,
if (clnt->cl_dentry) &p->pdo);
gss_pipes_dentries_destroy(auth); rpc_destroy_pipe_data(p->pipe);
rpc_put_sb_net(net); kfree(p);
}
} }
static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt, static void gss_pipe_free(struct gss_pipe *p)
struct rpc_auth *auth)
{ {
struct gss_auth *gss_auth = container_of(auth, struct gss_auth, if (p != NULL)
rpc_auth); __gss_pipe_free(p);
struct net *net = gss_auth->net;
struct super_block *sb;
int err = 0;
sb = rpc_get_sb_net(net);
if (sb) {
if (clnt->cl_dentry)
err = gss_pipes_dentries_create(auth);
rpc_put_sb_net(net);
}
return err;
} }
/* /*
...@@ -881,6 +886,7 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) ...@@ -881,6 +886,7 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
{ {
rpc_authflavor_t flavor = args->pseudoflavor; rpc_authflavor_t flavor = args->pseudoflavor;
struct gss_auth *gss_auth; struct gss_auth *gss_auth;
struct gss_pipe *gss_pipe;
struct rpc_auth * auth; struct rpc_auth * auth;
int err = -ENOMEM; /* XXX? */ int err = -ENOMEM; /* XXX? */
...@@ -915,39 +921,35 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) ...@@ -915,39 +921,35 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
atomic_set(&auth->au_count, 1); atomic_set(&auth->au_count, 1);
kref_init(&gss_auth->kref); kref_init(&gss_auth->kref);
err = rpcauth_init_credcache(auth);
if (err)
goto err_put_mech;
/* /*
* Note: if we created the old pipe first, then someone who * Note: if we created the old pipe first, then someone who
* examined the directory at the right moment might conclude * examined the directory at the right moment might conclude
* that we supported only the old pipe. So we instead create * that we supported only the old pipe. So we instead create
* the new pipe first. * the new pipe first.
*/ */
gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1, gss_pipe = gss_pipe_alloc(clnt, "gssd", &gss_upcall_ops_v1);
RPC_PIPE_WAIT_FOR_OPEN); if (IS_ERR(gss_pipe)) {
if (IS_ERR(gss_auth->pipe[1])) { err = PTR_ERR(gss_pipe);
err = PTR_ERR(gss_auth->pipe[1]); goto err_destroy_credcache;
goto err_put_mech;
} }
gss_auth->gss_pipe[1] = gss_pipe;
gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0, gss_pipe = gss_pipe_alloc(clnt, gss_auth->mech->gm_name,
RPC_PIPE_WAIT_FOR_OPEN); &gss_upcall_ops_v0);
if (IS_ERR(gss_auth->pipe[0])) { if (IS_ERR(gss_pipe)) {
err = PTR_ERR(gss_auth->pipe[0]); err = PTR_ERR(gss_pipe);
goto err_destroy_pipe_1; goto err_destroy_pipe_1;
} }
err = gss_pipes_dentries_create_net(clnt, auth); gss_auth->gss_pipe[0] = gss_pipe;
if (err)
goto err_destroy_pipe_0;
err = rpcauth_init_credcache(auth);
if (err)
goto err_unlink_pipes;
return auth; return auth;
err_unlink_pipes:
gss_pipes_dentries_destroy_net(clnt, auth);
err_destroy_pipe_0:
rpc_destroy_pipe_data(gss_auth->pipe[0]);
err_destroy_pipe_1: err_destroy_pipe_1:
rpc_destroy_pipe_data(gss_auth->pipe[1]); __gss_pipe_free(gss_auth->gss_pipe[1]);
err_destroy_credcache:
rpcauth_destroy_credcache(auth);
err_put_mech: err_put_mech:
gss_mech_put(gss_auth->mech); gss_mech_put(gss_auth->mech);
err_put_net: err_put_net:
...@@ -963,9 +965,8 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) ...@@ -963,9 +965,8 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
static void static void
gss_free(struct gss_auth *gss_auth) gss_free(struct gss_auth *gss_auth)
{ {
gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth); gss_pipe_free(gss_auth->gss_pipe[0]);
rpc_destroy_pipe_data(gss_auth->pipe[0]); gss_pipe_free(gss_auth->gss_pipe[1]);
rpc_destroy_pipe_data(gss_auth->pipe[1]);
gss_mech_put(gss_auth->mech); gss_mech_put(gss_auth->mech);
put_net(gss_auth->net); put_net(gss_auth->net);
kfree(gss_auth->target_name); kfree(gss_auth->target_name);
...@@ -985,14 +986,18 @@ gss_free_callback(struct kref *kref) ...@@ -985,14 +986,18 @@ gss_free_callback(struct kref *kref)
static void static void
gss_destroy(struct rpc_auth *auth) gss_destroy(struct rpc_auth *auth)
{ {
struct gss_auth *gss_auth; struct gss_auth *gss_auth = container_of(auth,
struct gss_auth, rpc_auth);
dprintk("RPC: destroying GSS authenticator %p flavor %d\n", dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
auth, auth->au_flavor); auth, auth->au_flavor);
gss_pipe_free(gss_auth->gss_pipe[0]);
gss_auth->gss_pipe[0] = NULL;
gss_pipe_free(gss_auth->gss_pipe[1]);
gss_auth->gss_pipe[1] = NULL;
rpcauth_destroy_credcache(auth); rpcauth_destroy_credcache(auth);
gss_auth = container_of(auth, struct gss_auth, rpc_auth);
kref_put(&gss_auth->kref, gss_free_callback); kref_put(&gss_auth->kref, gss_free_callback);
} }
...@@ -1676,8 +1681,6 @@ static const struct rpc_authops authgss_ops = { ...@@ -1676,8 +1681,6 @@ static const struct rpc_authops authgss_ops = {
.destroy = gss_destroy, .destroy = gss_destroy,
.lookup_cred = gss_lookup_cred, .lookup_cred = gss_lookup_cred,
.crcreate = gss_create_cred, .crcreate = gss_create_cred,
.pipes_create = gss_pipes_dentries_create,
.pipes_destroy = gss_pipes_dentries_destroy,
.list_pseudoflavors = gss_mech_list_pseudoflavors, .list_pseudoflavors = gss_mech_list_pseudoflavors,
.info2flavor = gss_mech_info2flavor, .info2flavor = gss_mech_info2flavor,
.flavor2info = gss_mech_flavor2info, .flavor2info = gss_mech_flavor2info,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment