Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124763
b: refs/heads/master
c: 34769fc
h: refs/heads/master
i:
  124761: 03676ea
  124759: 3264ca7
v: v3
  • Loading branch information
\"J. Bruce Fields\ authored and Trond Myklebust committed Dec 23, 2008
1 parent e4a11fa commit 683bad7
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5b7ddd4a7b19f913901140ef7807dbf5e2b301cd
refs/heads/master: 34769fc488b463cb753fc632f8f5ba56c918b7cb
116 changes: 96 additions & 20 deletions trunk/net/sunrpc/auth_gss/auth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@ struct gss_auth {
struct gss_api_mech *mech;
enum rpc_gss_svc service;
struct rpc_clnt *client;
struct dentry *dentry;
/*
* There are two upcall pipes; dentry[1], named "gssd", is used
* for the new text-based upcall; dentry[0] is named after the
* mechanism (for example, "krb5") and exists for
* backwards-compatibility with older gssd's.
*/
struct dentry *dentry[2];
};

/* pipe_version >= 0 if and only if someone has a pipe open. */
Expand All @@ -83,7 +89,8 @@ static struct rpc_wait_queue pipe_version_rpc_waitqueue;
static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);

static void gss_free_ctx(struct gss_cl_ctx *);
static struct rpc_pipe_ops gss_upcall_ops;
static struct rpc_pipe_ops gss_upcall_ops_v0;
static struct rpc_pipe_ops gss_upcall_ops_v1;

static inline struct gss_cl_ctx *
gss_get_ctx(struct gss_cl_ctx *ctx)
Expand Down Expand Up @@ -227,6 +234,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
return p;
}

#define UPCALL_BUF_LEN 128

struct gss_upcall_msg {
atomic_t count;
Expand All @@ -238,6 +246,7 @@ struct gss_upcall_msg {
struct rpc_wait_queue rpc_waitqueue;
wait_queue_head_t waitqueue;
struct gss_cl_ctx *ctx;
char databuf[UPCALL_BUF_LEN];
};

static int get_pipe_version(void)
Expand All @@ -247,7 +256,7 @@ static int get_pipe_version(void)
spin_lock(&pipe_version_lock);
if (pipe_version >= 0) {
atomic_inc(&pipe_users);
ret = 0;
ret = pipe_version;
} else
ret = -EAGAIN;
spin_unlock(&pipe_version_lock);
Expand Down Expand Up @@ -353,6 +362,29 @@ gss_upcall_callback(struct rpc_task *task)
gss_release_msg(gss_msg);
}

static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
{
gss_msg->msg.data = &gss_msg->uid;
gss_msg->msg.len = sizeof(gss_msg->uid);
}

static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg)
{
gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d\n",
gss_msg->auth->mech->gm_name,
gss_msg->uid);
gss_msg->msg.data = gss_msg->databuf;
BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN);
}

static void gss_encode_msg(struct gss_upcall_msg *gss_msg)
{
if (pipe_version == 0)
gss_encode_v0_msg(gss_msg);
else /* pipe_version == 1 */
gss_encode_v1_msg(gss_msg);
}

static inline struct gss_upcall_msg *
gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
{
Expand All @@ -367,15 +399,14 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
kfree(gss_msg);
return ERR_PTR(vers);
}
gss_msg->inode = RPC_I(gss_auth->dentry->d_inode);
gss_msg->inode = RPC_I(gss_auth->dentry[vers]->d_inode);
INIT_LIST_HEAD(&gss_msg->list);
rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
init_waitqueue_head(&gss_msg->waitqueue);
atomic_set(&gss_msg->count, 1);
gss_msg->msg.data = &gss_msg->uid;
gss_msg->msg.len = sizeof(gss_msg->uid);
gss_msg->uid = uid;
gss_msg->auth = gss_auth;
gss_encode_msg(gss_msg);
return gss_msg;
}

Expand Down Expand Up @@ -613,18 +644,36 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
return err;
}

static int
gss_pipe_open(struct inode *inode)
static int gss_pipe_open(struct inode *inode, int new_version)
{
int ret = 0;

spin_lock(&pipe_version_lock);
if (pipe_version < 0) {
pipe_version = 0;
/* First open of any gss pipe determines the version: */
pipe_version = new_version;
rpc_wake_up(&pipe_version_rpc_waitqueue);
wake_up(&pipe_version_waitqueue);
} else if (pipe_version != new_version) {
/* Trying to open a pipe of a different version */
ret = -EBUSY;
goto out;
}
atomic_inc(&pipe_users);
out:
spin_unlock(&pipe_version_lock);
return 0;
return ret;

}

static int gss_pipe_open_v0(struct inode *inode)
{
return gss_pipe_open(inode, 0);
}

static int gss_pipe_open_v1(struct inode *inode)
{
return gss_pipe_open(inode, 1);
}

static void
Expand Down Expand Up @@ -702,20 +751,38 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
atomic_set(&auth->au_count, 1);
kref_init(&gss_auth->kref);

gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name,
clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
if (IS_ERR(gss_auth->dentry)) {
err = PTR_ERR(gss_auth->dentry);
/*
* Note: if we created the old pipe first, then someone who
* examined the directory at the right moment might conclude
* that we supported only the old pipe. So we instead create
* the new pipe first.
*/
gss_auth->dentry[1] = rpc_mkpipe(clnt->cl_dentry,
"gssd",
clnt, &gss_upcall_ops_v1,
RPC_PIPE_WAIT_FOR_OPEN);
if (IS_ERR(gss_auth->dentry[1])) {
err = PTR_ERR(gss_auth->dentry[1]);
goto err_put_mech;
}

gss_auth->dentry[0] = rpc_mkpipe(clnt->cl_dentry,
gss_auth->mech->gm_name,
clnt, &gss_upcall_ops_v0,
RPC_PIPE_WAIT_FOR_OPEN);
if (IS_ERR(gss_auth->dentry[0])) {
err = PTR_ERR(gss_auth->dentry[0]);
goto err_unlink_pipe_1;
}
err = rpcauth_init_credcache(auth);
if (err)
goto err_unlink_pipe;
goto err_unlink_pipe_0;

return auth;
err_unlink_pipe:
rpc_unlink(gss_auth->dentry);
err_unlink_pipe_0:
rpc_unlink(gss_auth->dentry[0]);
err_unlink_pipe_1:
rpc_unlink(gss_auth->dentry[1]);
err_put_mech:
gss_mech_put(gss_auth->mech);
err_free:
Expand All @@ -728,7 +795,8 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
static void
gss_free(struct gss_auth *gss_auth)
{
rpc_unlink(gss_auth->dentry);
rpc_unlink(gss_auth->dentry[1]);
rpc_unlink(gss_auth->dentry[0]);
gss_mech_put(gss_auth->mech);

kfree(gss_auth);
Expand Down Expand Up @@ -1419,11 +1487,19 @@ static const struct rpc_credops gss_nullops = {
.crunwrap_resp = gss_unwrap_resp,
};

static struct rpc_pipe_ops gss_upcall_ops = {
static struct rpc_pipe_ops gss_upcall_ops_v0 = {
.upcall = gss_pipe_upcall,
.downcall = gss_pipe_downcall,
.destroy_msg = gss_pipe_destroy_msg,
.open_pipe = gss_pipe_open_v0,
.release_pipe = gss_pipe_release,
};

static struct rpc_pipe_ops gss_upcall_ops_v1 = {
.upcall = gss_pipe_upcall,
.downcall = gss_pipe_downcall,
.destroy_msg = gss_pipe_destroy_msg,
.open_pipe = gss_pipe_open,
.open_pipe = gss_pipe_open_v1,
.release_pipe = gss_pipe_release,
};

Expand Down

0 comments on commit 683bad7

Please sign in to comment.