* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: sec_gss.c,v 1.4 2005/04/13 09:49:50 yury Exp $
*/
#ifndef EXPORT_SYMTAB
#include "gss_internal.h"
#include "gss_api.h"
-#define GSS_CREDCACHE_EXPIRE (60) /* 1 minute */
+#define GSS_CREDCACHE_EXPIRE (30 * 60) /* 30 minute */
+/* not used now */
+#if 0
#define GSS_CRED_EXPIRE (8 * 60 * 60) /* 8 hours */
#define GSS_CRED_SIGN_SIZE (1024)
#define GSS_CRED_VERIFY_SIZE (56)
+#endif
#define LUSTRE_PIPEDIR "/lustre"
* gss security init/fini helper *
**********************************************/
-#define SECINIT_RPC_TIMEOUT (10)
+#define SECINIT_RPC_TIMEOUT (30)
#define SECFINI_RPC_TIMEOUT (10)
static int secinit_compose_request(struct obd_import *imp,
char *buf, int bufsize,
+ int lustre_srv,
+ uid_t uid, gid_t gid,
+ long token_size,
char __user *token)
{
struct ptlrpcs_wire_hdr *hdr;
struct lustre_msg *lmsg;
- char __user *token_buf;
- __u64 token_size;
+ struct mds_req_sec_desc *secdesc;
+ int size = sizeof(*secdesc);
__u32 lmsg_size, *p;
- int rc;
+ int rc;
- lmsg_size = lustre_msg_size(0, NULL);
+ lmsg_size = lustre_msg_size(1, &size);
- if (copy_from_user(&token_size, token, sizeof(token_size))) {
- CERROR("read token error\n");
- return -EFAULT;
- }
if (sizeof(*hdr) + lmsg_size + size_round(token_size) > bufsize) {
- CERROR("token size "LPU64" too large\n", token_size);
+ CERROR("token size %ld too large\n", token_size);
return -EINVAL;
}
- if (copy_from_user(&token_buf, (token + sizeof(token_size)),
- sizeof(void*))) {
- CERROR("read token buf pointer error\n");
- return -EFAULT;
- }
-
/* security wire hdr */
hdr = buf_to_sec_hdr(buf);
- hdr->flavor = cpu_to_le32(PTLRPC_SEC_GSS);
- hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_NONE);
+ hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_GSS_NONE);
hdr->msg_len = cpu_to_le32(lmsg_size);
- hdr->sec_len = cpu_to_le32(7 * 4 + token_size);
+ hdr->sec_len = cpu_to_le32(8 * 4 + token_size);
- /* lustre message */
+ /* lustre message & secdesc */
lmsg = buf_to_lustre_msg(buf);
- lustre_init_msg(lmsg, 0, NULL, NULL);
+
+ lustre_init_msg(lmsg, 1, &size, NULL);
+ secdesc = lustre_msg_buf(lmsg, 0, size);
+ secdesc->rsd_uid = secdesc->rsd_fsuid = uid;
+ secdesc->rsd_gid = secdesc->rsd_fsgid = gid;
+ secdesc->rsd_cap = secdesc->rsd_ngroups = 0;
+
lmsg->handle = imp->imp_remote_handle;
lmsg->type = PTL_RPC_MSG_REQUEST;
lmsg->opc = SEC_INIT;
/* gss hdr */
*p++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); /* gss version */
- *p++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); /* subflavor */
- *p++ = cpu_to_le32(PTLRPC_GSS_PROC_INIT); /* proc */
+ *p++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); /* subflavor */
+ *p++ = cpu_to_le32(PTLRPCS_GSS_PROC_INIT); /* proc */
*p++ = cpu_to_le32(0); /* seq */
- *p++ = cpu_to_le32(PTLRPC_GSS_SVC_NONE); /* service */
+ *p++ = cpu_to_le32(PTLRPCS_GSS_SVC_NONE); /* service */
*p++ = cpu_to_le32(0); /* context handle */
+ /* plus lustre svc type */
+ *p++ = cpu_to_le32(lustre_srv);
+
/* now the token part */
- *p++ = (__u32)(cpu_to_le64(token_size));
+ *p++ = cpu_to_le32((__u32) token_size);
LASSERT(((char *)p - buf) + token_size <= bufsize);
- rc = copy_from_user(p, token_buf, token_size);
+ rc = copy_from_user(p, token, token_size);
if (rc) {
CERROR("can't copy token\n");
return -EFAULT;
}
static int secinit_parse_reply(char *repbuf, int replen,
- char __user *outbuf, int outlen)
+ char __user *outbuf, long outlen)
{
- __u32 *p = (__u32 *)repbuf;
- __u32 lmsg_len, sec_len, status, major, minor, seq, obj_len, round_len;
- __u32 effective = 0;
+ __u32 *p = (__u32 *)repbuf;
+ struct ptlrpcs_wire_hdr *hdr = (struct ptlrpcs_wire_hdr *) repbuf;
+ __u32 lmsg_len, sec_len, status;
+ __u32 major, minor, seq, obj_len, round_len;
+ __u32 effective = 0;
if (replen <= (4 + 6) * 4) {
CERROR("reply size %d too small\n", replen);
return -EINVAL;
}
+ hdr->flavor = le32_to_cpu(hdr->flavor);
+ hdr->msg_len = le32_to_cpu(hdr->msg_len);
+ hdr->sec_len = le32_to_cpu(hdr->sec_len);
+
lmsg_len = le32_to_cpu(p[2]);
sec_len = le32_to_cpu(p[3]);
/* sanity checks */
- if (p[0] != cpu_to_le32(PTLRPC_SEC_GSS) ||
- p[1] != cpu_to_le32(PTLRPC_SEC_TYPE_NONE)) {
+ if (hdr->flavor != PTLRPCS_FLVR_GSS_NONE) {
CERROR("unexpected reply\n");
return -EINVAL;
}
- if (lmsg_len % 8 ||
- 4 * 4 + lmsg_len + sec_len > replen) {
+ if (hdr->msg_len % 8 ||
+ sizeof(*hdr) + hdr->msg_len + hdr->sec_len > replen) {
CERROR("unexpected reply\n");
return -EINVAL;
}
- if (sec_len > outlen) {
+ if (hdr->sec_len > outlen) {
CERROR("outbuf too small\n");
return -EINVAL;
}
- p += 4; /* skip hdr */
- p += lmsg_len / 4; /* skip lmsg */
+ p = (__u32 *) buf_to_sec_data(repbuf);
effective = 0;
status = le32_to_cpu(*p++);
seq = le32_to_cpu(*p++);
effective += 4 * 4;
- copy_to_user(outbuf, &status, 4);
+ if (copy_to_user(outbuf, &status, 4))
+ return -EFAULT;
outbuf += 4;
- copy_to_user(outbuf, &major, 4);
+ if (copy_to_user(outbuf, &major, 4))
+ return -EFAULT;
outbuf += 4;
- copy_to_user(outbuf, &minor, 4);
+ if (copy_to_user(outbuf, &minor, 4))
+ return -EFAULT;
outbuf += 4;
- copy_to_user(outbuf, &seq, 4);
+ if (copy_to_user(outbuf, &seq, 4))
+ return -EFAULT;
outbuf += 4;
obj_len = le32_to_cpu(*p++);
round_len = (obj_len + 3) & ~ 3;
- copy_to_user(outbuf, &obj_len, 4);
+ if (copy_to_user(outbuf, &obj_len, 4))
+ return -EFAULT;
outbuf += 4;
- copy_to_user(outbuf, (char *)p, round_len);
+ if (copy_to_user(outbuf, (char *)p, round_len))
+ return -EFAULT;
p += round_len / 4;
outbuf += round_len;
effective += 4 + round_len;
obj_len = le32_to_cpu(*p++);
round_len = (obj_len + 3) & ~ 3;
- copy_to_user(outbuf, &obj_len, 4);
+ if (copy_to_user(outbuf, &obj_len, 4))
+ return -EFAULT;
outbuf += 4;
- copy_to_user(outbuf, (char *)p, round_len);
+ if (copy_to_user(outbuf, (char *)p, round_len))
+ return -EFAULT;
p += round_len / 4;
outbuf += round_len;
effective += 4 + round_len;
return effective;
}
-/* input:
- * 1. ptr to uuid
- * 2. ptr to send_token
- * 3. ptr to output buffer
- * 4. output buffer size
- * output:
- * 1. return code. 0 is success
- * 2. no meaning
- * 3. ptr output data
- * 4. output data size
- *
- * return:
- * < 0: error
- * = 0: success
- *
- * FIXME This interface looks strange, should be reimplemented
- */
+/* XXX move to where lgssd could see */
+struct lgssd_ioctl_param {
+ int version; /* in */
+ char *uuid; /* in */
+ int lustre_svc; /* in */
+ uid_t uid; /* in */
+ gid_t gid; /* in */
+ long send_token_size;/* in */
+ char *send_token; /* in */
+ long reply_buf_size; /* in */
+ char *reply_buf; /* in */
+ long status; /* out */
+ long reply_length; /* out */
+};
+
static int gss_send_secinit_rpc(__user char *buffer, unsigned long count)
{
- struct obd_import *imp;
- const int reqbuf_size = 1024;
- const int repbuf_size = 1024;
- char *reqbuf, *repbuf;
- struct obd_device *obd;
- char obdname[64];
- long inbuf[4], lsize;
- int rc, reqlen, replen;
-
- if (count != 4 * sizeof(long)) {
- CERROR("count %lu\n", count);
+ struct obd_import *imp;
+ struct ptlrpc_request *request = NULL;
+ struct lgssd_ioctl_param param;
+ const int reqbuf_size = 1024;
+ const int repbuf_size = 1024;
+ char *reqbuf, *repbuf;
+ struct obd_device *obd;
+ char obdname[64];
+ long lsize;
+ int rc, reqlen, replen;
+
+ if (count != sizeof(param)) {
+ CERROR("ioctl size %lu, expect %d, please check lgssd version\n",
+ count, sizeof(param));
RETURN(-EINVAL);
}
- if (copy_from_user(inbuf, buffer, count)) {
- CERROR("Invalid pointer\n");
+ if (copy_from_user(¶m, buffer, sizeof(param))) {
+ CERROR("failed copy data from lgssd\n");
RETURN(-EFAULT);
}
+ if (param.version != GSSD_INTERFACE_VERSION) {
+ CERROR("gssd interface version %d (expect %d)\n",
+ param.version, GSSD_INTERFACE_VERSION);
+ RETURN(-EINVAL);
+ }
+
/* take name */
- if (strncpy_from_user(obdname, (char *)inbuf[0],
+ if (strncpy_from_user(obdname, param.uuid,
sizeof(obdname)) <= 0) {
CERROR("Invalid obdname pointer\n");
RETURN(-EFAULT);
CERROR("no such obd %s\n", obdname);
RETURN(-EINVAL);
}
- if (strcmp(obd->obd_type->typ_name, "mdc") &&
- strcmp(obd->obd_type->typ_name, "osc")) {
- CERROR("%s not a mdc/osc device\n", obdname);
- RETURN(-EINVAL);
- }
imp = class_import_get(obd->u.cli.cl_import);
if (!reqbuf || !repbuf) {
CERROR("Can't alloc buffer: %p/%p\n", reqbuf, repbuf);
- GOTO(out_free, rc = -ENOMEM);
+ param.status = -ENOMEM;
+ goto out_copy;
}
/* get token */
reqlen = secinit_compose_request(imp, reqbuf, reqbuf_size,
- (char *)inbuf[1]);
- if (reqlen < 0)
- GOTO(out_free, rc = reqlen);
+ param.lustre_svc,
+ param.uid, param.gid,
+ param.send_token_size,
+ param.send_token);
+ if (reqlen < 0) {
+ param.status = reqlen;
+ goto out_copy;
+ }
- replen = repbuf_size;
- rc = ptlrpc_do_rawrpc(imp, reqbuf, reqlen,
- repbuf, &replen, SECINIT_RPC_TIMEOUT);
- if (rc)
- GOTO(out_free, rc);
+ request = ptl_do_rawrpc(imp, reqbuf, reqbuf_size, reqlen,
+ repbuf, repbuf_size, &replen,
+ SECINIT_RPC_TIMEOUT, &rc);
+ if (request == NULL || rc) {
+ param.status = rc;
+ goto out_copy;
+ }
- if (replen > inbuf[3]) {
+ if (replen > param.reply_buf_size) {
CERROR("output buffer size %ld too small, need %d\n",
- inbuf[3], replen);
- GOTO(out_free, rc = -EINVAL);
+ param.reply_buf_size, replen);
+ param.status = -EINVAL;
+ goto out_copy;
}
lsize = secinit_parse_reply(repbuf, replen,
- (char *)inbuf[2], (int)inbuf[3]);
- if (lsize < 0)
- GOTO(out_free, rc = (int)lsize);
+ param.reply_buf, param.reply_buf_size);
+ if (lsize < 0) {
+ param.status = (int) lsize;
+ goto out_copy;
+ }
- copy_to_user(buffer + 3 * sizeof(long), &lsize, sizeof(lsize));
- lsize = 0;
- copy_to_user((char*)buffer, &lsize, sizeof(lsize));
- rc = 0;
-out_free:
- class_import_put(imp);
- if (repbuf)
- OBD_FREE(repbuf, repbuf_size);
- if (reqbuf)
- OBD_FREE(reqbuf, reqbuf_size);
- RETURN(rc);
-}
+ param.status = 0;
+ param.reply_length = lsize;
-static int gss_send_secfini_rpc(struct obd_import *imp,
- char *reqbuf, int reqlen)
-{
- const int repbuf_size = 1024;
- char *repbuf;
- int replen = repbuf_size;
- int rc;
+out_copy:
+ if (copy_to_user(buffer, ¶m, sizeof(param)))
+ rc = -EFAULT;
+ else
+ rc = 0;
- OBD_ALLOC(repbuf, repbuf_size);
- if (!repbuf) {
- CERROR("Out of memory\n");
- return -ENOMEM;
+ class_import_put(imp);
+ if (request == NULL) {
+ if (repbuf)
+ OBD_FREE(repbuf, repbuf_size);
+ if (reqbuf)
+ OBD_FREE(reqbuf, reqbuf_size);
+ } else {
+ rawrpc_req_finished(request);
}
-
- rc = ptlrpc_do_rawrpc(imp, reqbuf, reqlen, repbuf, &replen,
- SECFINI_RPC_TIMEOUT);
-
- OBD_FREE(repbuf, repbuf_size);
- return rc;
+ RETURN(rc);
}
/**********************************************
#ifdef __KERNEL__
spinlock_t gs_lock;
struct list_head gs_upcalls;
- char gs_pipepath[64];
+ char *gs_pipepath;
struct dentry *gs_depipe;
#endif
};
static rwlock_t gss_ctx_lock = RW_LOCK_UNLOCKED;
+struct gss_upcall_msg_data {
+ __u32 gum_uid;
+ __u32 gum_svc;
+ __u32 gum_nal;
+ __u32 gum_netid;
+ __u64 gum_nid;
+};
+
struct gss_upcall_msg {
struct rpc_pipe_msg gum_base;
atomic_t gum_refcount;
struct gss_sec *gum_gsec;
wait_queue_head_t gum_waitq;
char gum_obdname[64];
- uid_t gum_uid;
- __u32 gum_ip; /* XXX IPv6? */
- __u32 gum_svc;
- __u32 gum_pad;
+ struct gss_upcall_msg_data gum_data;
};
/**********************************************
return;
}
LASSERT(list_empty(&gmsg->gum_list));
+ LASSERT(list_empty(&gmsg->gum_base.list));
OBD_FREE(gmsg, sizeof(*gmsg));
EXIT;
}
EXIT;
return;
}
- /* FIXME should not do this. when we in upper upcall queue,
- * downcall will call unhash_msg, thus later put_msg might
- * free msg buffer while it's not dequeued XXX */
- list_del_init(&gmsg->gum_base.list);
- /* FIXME */
list_del_init(&gmsg->gum_list);
wake_up(&gmsg->gum_waitq);
static
struct gss_upcall_msg * gss_find_upcall(struct gss_sec *gsec,
char *obdname,
- uid_t uid, __u32 dest_ip)
+ struct gss_upcall_msg_data *gmd)
{
struct gss_upcall_msg *gmsg;
ENTRY;
list_for_each_entry(gmsg, &gsec->gs_upcalls, gum_list) {
- if (gmsg->gum_uid != uid)
- continue;
- if (gmsg->gum_ip != dest_ip)
+ if (memcmp(&gmsg->gum_data, gmd, sizeof(*gmd)))
continue;
if (strcmp(gmsg->gum_obdname, obdname))
continue;
atomic_inc(&gmsg->gum_refcount);
CDEBUG(D_SEC, "found gmsg at %p: obdname %s, uid %d, ref %d\n",
- gmsg, obdname, uid, atomic_read(&gmsg->gum_refcount));
+ gmsg, obdname, gmd->gum_uid,
+ atomic_read(&gmsg->gum_refcount));
RETURN(gmsg);
}
RETURN(NULL);
}
static void gss_init_upcall_msg(struct gss_upcall_msg *gmsg,
- struct gss_sec *gsec,
- char *obdname,
- uid_t uid, __u32 dest_ip, __u32 svc)
+ struct gss_sec *gsec, char *obdname,
+ struct gss_upcall_msg_data *gmd)
{
struct rpc_pipe_msg *rpcmsg;
ENTRY;
atomic_set(&gmsg->gum_refcount, 2);
gmsg->gum_gsec = gsec;
strncpy(gmsg->gum_obdname, obdname, sizeof(gmsg->gum_obdname));
- gmsg->gum_uid = uid;
- gmsg->gum_ip = dest_ip;
- gmsg->gum_svc = svc;
+ memcpy(&gmsg->gum_data, gmd, sizeof(*gmd));
rpcmsg = &gmsg->gum_base;
- rpcmsg->data = &gmsg->gum_uid;
- rpcmsg->len = sizeof(gmsg->gum_uid) + sizeof(gmsg->gum_ip) +
- sizeof(gmsg->gum_svc) + sizeof(gmsg->gum_pad);
+ rpcmsg->data = &gmsg->gum_data;
+ rpcmsg->len = sizeof(gmsg->gum_data);
EXIT;
}
#endif /* __KERNEL__ */
/********************************************
- * gss cred manupulation helpers *
+ * gss cred manipulation helpers *
********************************************/
+#if 0
static
int gss_cred_is_uptodate_ctx(struct ptlrpc_cred *cred)
{
int res = 0;
read_lock(&gss_ctx_lock);
- if ((cred->pc_flags & PTLRPC_CRED_UPTODATE) && gcred->gc_ctx)
+ if (((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
+ PTLRPC_CRED_UPTODATE) &&
+ gcred->gc_ctx)
res = 1;
read_unlock(&gss_ctx_lock);
return res;
}
+#endif
static inline
struct gss_cl_ctx * gss_get_ctx(struct gss_cl_ctx *ctx)
write_lock(&gss_ctx_lock);
old = gcred->gc_ctx;
gcred->gc_ctx = ctx;
- cred->pc_flags |= PTLRPC_CRED_UPTODATE;
+ set_bit(PTLRPC_CRED_UPTODATE_BIT, &cred->pc_flags);
write_unlock(&gss_ctx_lock);
if (old)
gss_put_ctx(old);
- CWARN("client refreshed gss cred %p(uid %u)\n", cred, cred->pc_uid);
+ CDEBUG(D_SEC, "client refreshed gss cred %p(uid %u)\n",
+ cred, cred->pc_uid);
EXIT;
}
*/
static
int gss_parse_init_downcall(struct gss_api_mech *gm, rawobj_t *buf,
- struct gss_cl_ctx **gc, struct vfs_cred *vcred,
- __u32 *dest_ip, int *gss_err)
+ struct gss_cl_ctx **gc,
+ struct gss_upcall_msg_data *gmd, int *gss_err)
{
- char *p = buf->data;
- __u32 len = buf->len;
+ char *p = (char *)buf->data;
struct gss_cl_ctx *ctx;
- rawobj_t tmp_buf;
+ __u32 len = buf->len;
unsigned int timeout;
- int err = -EIO;
+ rawobj_t tmp_buf;
+ int err = -EPERM;
ENTRY;
*gc = NULL;
+ *gss_err = 0;
OBD_ALLOC(ctx, sizeof(*ctx));
if (!ctx)
spin_lock_init(&ctx->gc_seq_lock);
atomic_set(&ctx->gc_refcount,1);
- if (simple_get_bytes(&p, &len, &vcred->vc_uid, sizeof(vcred->vc_uid)))
- GOTO(err_free_ctx, err);
- vcred->vc_pag = vcred->vc_uid; /* FIXME */
- if (simple_get_bytes(&p, &len, dest_ip, sizeof(*dest_ip)))
- GOTO(err_free_ctx, err);
+ if (simple_get_bytes(&p, &len, &gmd->gum_uid, sizeof(gmd->gum_uid)))
+ goto err_free_ctx;
+ if (simple_get_bytes(&p, &len, &gmd->gum_svc, sizeof(gmd->gum_svc)))
+ goto err_free_ctx;
+ if (simple_get_bytes(&p, &len, &gmd->gum_nal, sizeof(gmd->gum_nal)))
+ goto err_free_ctx;
+ if (simple_get_bytes(&p, &len, &gmd->gum_netid, sizeof(gmd->gum_netid)))
+ goto err_free_ctx;
+ if (simple_get_bytes(&p, &len, &gmd->gum_nid, sizeof(gmd->gum_nid)))
+ goto err_free_ctx;
/* FIXME: discarded timeout for now */
if (simple_get_bytes(&p, &len, &timeout, sizeof(timeout)))
- GOTO(err_free_ctx, err);
- *gss_err = 0;
+ goto err_free_ctx;
if (simple_get_bytes(&p, &len, &ctx->gc_win, sizeof(ctx->gc_win)))
- GOTO(err_free_ctx, err);
- /* gssd signals an error by passing ctx->gc_win = 0: */
+ goto err_free_ctx;
+
+ /* lgssd signals an error by passing ctx->gc_win = 0: */
if (!ctx->gc_win) {
- /* in which case the next int is an error code: */
- if (simple_get_bytes(&p, &len, gss_err, sizeof(*gss_err)))
- GOTO(err_free_ctx, err);
- GOTO(err_free_ctx, err = 0);
+ /* in which case the next 2 int are:
+ * - rpc error
+ * - gss error
+ */
+ if (simple_get_bytes(&p, &len, &err, sizeof(err))) {
+ err = -EPERM;
+ goto err_free_ctx;
+ }
+ if (simple_get_bytes(&p, &len, gss_err, sizeof(*gss_err))) {
+ err = -EPERM;
+ goto err_free_ctx;
+ }
+ if (err == 0 && *gss_err == 0) {
+ CERROR("no error passed from downcall\n");
+ err = -EPERM;
+ }
+ goto err_free_ctx;
}
+
if (rawobj_extract_local(&tmp_buf, (__u32 **) ((void *)&p), &len))
- GOTO(err_free_ctx, err);
+ goto err_free_ctx;
if (rawobj_dup(&ctx->gc_wire_ctx, &tmp_buf)) {
- GOTO(err_free_ctx, err = -ENOMEM);
+ err = -ENOMEM;
+ goto err_free_ctx;
}
if (rawobj_extract_local(&tmp_buf, (__u32 **) ((void *)&p), &len))
- GOTO(err_free_wire_ctx, err);
+ goto err_free_wire_ctx;
if (len) {
CERROR("unexpected trailing %u bytes\n", len);
- GOTO(err_free_wire_ctx, err);
+ goto err_free_wire_ctx;
}
if (kgss_import_sec_context(&tmp_buf, gm, &ctx->gc_gss_ctx))
- GOTO(err_free_wire_ctx, err);
+ goto err_free_wire_ctx;
*gc = ctx;
RETURN(0);
* cred APIs *
***************************************/
#ifdef __KERNEL__
+#define CRED_REFRESH_UPCALL_TIMEOUT (50)
static int gss_cred_refresh(struct ptlrpc_cred *cred)
{
struct obd_import *import;
struct gss_sec *gsec;
struct gss_upcall_msg *gss_msg, *gss_new;
+ struct gss_upcall_msg_data gmd;
struct dentry *dentry;
char *obdname, *obdtype;
wait_queue_t wait;
uid_t uid = cred->pc_uid;
- ptl_nid_t peer_nid;
- __u32 dest_ip, svc;
int res;
ENTRY;
- if (ptlrpcs_cred_is_uptodate(cred))
+ might_sleep();
+
+ /* any flags means it has been handled, do nothing */
+ if (cred->pc_flags & PTLRPC_CRED_FLAGS_MASK)
RETURN(0);
LASSERT(cred->pc_sec);
RETURN(-EINVAL);
}
- peer_nid = import->imp_connection->c_peer.peer_id.nid;
- dest_ip = (__u32) (peer_nid & 0xFFFFFFFF);
+ gmd.gum_uid = uid;
+ gmd.gum_nal = import->imp_connection->c_peer.peer_ni->pni_number;
+ gmd.gum_netid = 0;
+ gmd.gum_nid = import->imp_connection->c_peer.peer_id.nid;
obdtype = import->imp_obd->obd_type->typ_name;
if (!strcmp(obdtype, "mdc"))
- svc = 0;
+ gmd.gum_svc = LUSTRE_GSS_SVC_MDS;
else if (!strcmp(obdtype, "osc"))
- svc = 1;
+ gmd.gum_svc = LUSTRE_GSS_SVC_OSS;
else {
CERROR("gss on %s?\n", obdtype);
RETURN(-EINVAL);
gss_new = NULL;
res = 0;
- CWARN("Initiate gss context %p(%u@%s)\n",
+ CDEBUG(D_SEC, "Initiate gss context %p(%u@%s)\n",
container_of(cred, struct gss_cred, gc_base),
uid, import->imp_target_uuid.uuid);
again:
spin_lock(&gsec->gs_lock);
- gss_msg = gss_find_upcall(gsec, obdname, uid, dest_ip);
+ gss_msg = gss_find_upcall(gsec, obdname, &gmd);
if (gss_msg) {
- spin_unlock(&gsec->gs_lock);
+ if (gss_new) {
+ OBD_FREE(gss_new, sizeof(*gss_new));
+ gss_new = NULL;
+ }
GOTO(waiting, res);
}
+
if (!gss_new) {
spin_unlock(&gsec->gs_lock);
OBD_ALLOC(gss_new, sizeof(*gss_new));
- if (!gss_new) {
- CERROR("fail to alloc memory\n");
+ if (!gss_new)
RETURN(-ENOMEM);
- }
goto again;
}
/* so far we'v created gss_new */
- gss_init_upcall_msg(gss_new, gsec, obdname, uid, dest_ip, svc);
-
- if (gss_cred_is_uptodate_ctx(cred)) {
- /* someone else had done it for us, simply cancel
- * our own upcall */
- CDEBUG(D_SEC, "cred("LPU64"/%u) has been refreshed by someone "
- "else, simply drop our request\n",
- cred->pc_pag, cred->pc_uid);
+ gss_init_upcall_msg(gss_new, gsec, obdname, &gmd);
+
+ /* we'v created upcall msg, nobody else should touch the
+ * flag of this cred, unless be set as dead/expire by
+ * administrator via lctl etc.
+ */
+ if (cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) {
+ CWARN("cred %p("LPU64"/%u) was set flags %lx unexpectedly\n",
+ cred, cred->pc_pag, cred->pc_uid, cred->pc_flags);
+ cred->pc_flags |= PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR;
gss_unhash_msg_nolock(gss_new);
spin_unlock(&gsec->gs_lock);
gss_release_msg(gss_new);
CERROR("rpc_queue_upcall failed: %d\n", res);
gss_unhash_msg(gss_new);
gss_release_msg(gss_new);
+ cred->pc_flags |= PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR;
RETURN(res);
}
gss_msg = gss_new;
+ spin_lock(&gsec->gs_lock);
waiting:
+ /* upcall might finish quickly */
+ if (list_empty(&gss_msg->gum_list)) {
+ spin_unlock(&gsec->gs_lock);
+ res = 0;
+ goto out;
+ }
+
init_waitqueue_entry(&wait, current);
- spin_lock(&gsec->gs_lock);
- add_wait_queue(&gss_msg->gum_waitq, &wait);
set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&gss_msg->gum_waitq, &wait);
spin_unlock(&gsec->gs_lock);
- schedule();
+ if (gss_new)
+ res = schedule_timeout(CRED_REFRESH_UPCALL_TIMEOUT * HZ);
+ else {
+ schedule();
+ res = 0;
+ }
remove_wait_queue(&gss_msg->gum_waitq, &wait);
+
+ /* - the one who refresh the cred for us should also be responsible
+ * to set the status of cred, we can simply return.
+ * - if cred flags has been set, we also don't need to do that again,
+ * no matter signal pending or timeout etc.
+ */
+ if (!gss_new || cred->pc_flags & PTLRPC_CRED_FLAGS_MASK)
+ goto out;
+
if (signal_pending(current)) {
- CERROR("interrupted gss upcall %p\n", gss_msg);
+ CERROR("%s: cred %p: interrupted upcall\n",
+ current->comm, cred);
+ cred->pc_flags |= PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR;
res = -EINTR;
- }
+ } else if (res == 0) {
+ CERROR("cred %p: upcall timedout\n", cred);
+ set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags);
+ res = -ETIMEDOUT;
+ } else
+ res = 0;
+
+out:
gss_release_msg(gss_msg);
+
RETURN(res);
}
#else /* !__KERNEL__ */
LASSERT(mech);
rc = gss_parse_init_downcall(mech, &obj, &ctx, &vcred, &dest_ip,
&gss_err);
- if (rc) {
- CERROR("parse init downcall error %d\n", rc);
- goto err_out;
- }
-
- if (gss_err) {
- CERROR("cred fresh got gss error %x\n", gss_err);
- rc = -EINVAL;
+ if (rc || gss_err) {
+ CERROR("parse init downcall: rpc %d, gss 0x%x\n", rc, gss_err);
+ if (rc != -ERESTART || gss_err != 0)
+ set_bit(PTLRPC_CRED_ERROR_BIT, &cred->pc_flags);
+ if (rc == 0)
+ rc = -EPERM;
goto err_out;
}
+ LASSERT(ctx);
gss_cred_set_ctx(cred, ctx);
LASSERT(gss_cred_is_uptodate_ctx(cred));
return 0;
err_out:
- cred->pc_flags |= PTLRPC_CRED_DEAD;
+ set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags);
return rc;
}
#endif
static int gss_cred_match(struct ptlrpc_cred *cred,
- struct ptlrpc_request *req,
struct vfs_cred *vcred)
{
RETURN(cred->pc_pag == vcred->vc_pag);
spin_unlock(&ctx->gc_seq_lock);
*vp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); /* version */
- *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); /* subflavor */
+ *vp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); /* subflavor */
*vp++ = cpu_to_le32(ctx->gc_proc); /* proc */
*vp++ = cpu_to_le32(seqnum); /* seq */
- *vp++ = cpu_to_le32(PTLRPC_GSS_SVC_INTEGRITY); /* service */
+ *vp++ = cpu_to_le32(PTLRPCS_GSS_SVC_INTEGRITY); /* service */
vlen -= 5 * 4;
if (rawobj_serialize(&ctx->gc_wire_ctx, &vp, &vlen)) {
vlen -= 4;
mic.len = vlen;
- mic.data = (char *) vp;
+ mic.data = (unsigned char *)vp;
CDEBUG(D_SEC, "reqbuf at %p, lmsg at %p, len %d, mic at %p, len %d\n",
req->rq_reqbuf, lmsg.data, lmsg.len, mic.data, mic.len);
major = kgss_get_mic(ctx->gc_gss_ctx, GSS_C_QOP_DEFAULT, &lmsg, &mic);
if (major) {
- CERROR("gss compute mic error, major %x\n", major);
+ CERROR("cred %p: req %p compute mic error, major %x\n",
+ cred, req, major);
rc = -EACCES;
goto out;
}
vlen -= 3 * 4;
switch (proc) {
- case PTLRPC_GSS_PROC_DATA:
+ case PTLRPCS_GSS_PROC_DATA:
seq = le32_to_cpu(*vp++);
svc = le32_to_cpu(*vp++);
- if (svc != PTLRPC_GSS_SVC_INTEGRITY) {
+ if (svc != PTLRPCS_GSS_SVC_INTEGRITY) {
CERROR("Unknown svc %d\n", svc);
RETURN(-EPROTO);
}
CERROR("vlen %d, mic.len %d\n", vlen, mic.len);
RETURN(-EINVAL);
}
- mic.data = (char *) vp;
+ mic.data = (unsigned char *)vp;
gcred = container_of(cred, struct gss_cred, gc_base);
ctx = gss_cred_get_ctx(cred);
major = kgss_verify_mic(ctx->gc_gss_ctx, &lmsg, &mic, NULL);
if (major != GSS_S_COMPLETE) {
- CERROR("gss verify mic error: major %x\n", major);
- GOTO(proc_data_out, rc = -EINVAL);
+ CERROR("cred %p: req %p verify mic error: major %x\n",
+ cred, req, major);
+
+ if (major == GSS_S_CREDENTIALS_EXPIRED ||
+ major == GSS_S_CONTEXT_EXPIRED) {
+ ptlrpcs_cred_expire(cred);
+ req->rq_ptlrpcs_restart = 1;
+ rc = 0;
+ } else
+ rc = -EINVAL;
+
+ GOTO(proc_data_out, rc);
}
req->rq_repmsg = (struct lustre_msg *) lmsg.data;
proc_data_out:
gss_put_ctx(ctx);
break;
- case PTLRPC_GSS_PROC_ERR:
+ case PTLRPCS_GSS_PROC_ERR:
major = le32_to_cpu(*vp++);
minor = le32_to_cpu(*vp++);
/* server return NO_CONTEXT might be caused by context expire
req, cred, (major == GSS_S_NO_CONTEXT) ?
"NO_CONTEXT" : "BAD_SIG");
- ptlrpcs_cred_die(cred);
- rc = ptlrpcs_req_replace_dead_cred(req);
- if (!rc)
- req->rq_ptlrpcs_restart = 1;
- else
- CERROR("replace dead cred failed %d\n", rc);
+ ptlrpcs_cred_expire(cred);
+ req->rq_ptlrpcs_restart = 1;
+ rc = 0;
} else {
- CERROR("Unrecognized gss error (%x/%x)\n",
- major, minor);
+ CERROR("req %p: unrecognized gss error (%x/%x)\n",
+ req, major, minor);
rc = -EACCES;
}
break;
spin_unlock(&ctx->gc_seq_lock);
*vp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); /* version */
- *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5P); /* subflavor */
+ *vp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5P); /* subflavor */
*vp++ = cpu_to_le32(ctx->gc_proc); /* proc */
*vp++ = cpu_to_le32(seqnum); /* seq */
- *vp++ = cpu_to_le32(PTLRPC_GSS_SVC_PRIVACY); /* service */
+ *vp++ = cpu_to_le32(PTLRPCS_GSS_SVC_PRIVACY); /* service */
vlen -= 5 * 4;
if (rawobj_serialize(&ctx->gc_wire_ctx, &vp, &vlen)) {
vlen -= 4;
msg_buf.buf = (__u8 *) req->rq_reqmsg - GSS_PRIVBUF_PREFIX_LEN;
- msg_buf.buflen = req->rq_reqlen + GSS_PRIVBUF_PREFIX_LEN + GSS_PRIVBUF_SUFFIX_LEN;
+ msg_buf.buflen = req->rq_reqlen + GSS_PRIVBUF_PREFIX_LEN +
+ GSS_PRIVBUF_SUFFIX_LEN;
msg_buf.dataoff = GSS_PRIVBUF_PREFIX_LEN;
msg_buf.datalen = req->rq_reqlen;
major = kgss_wrap(ctx->gc_gss_ctx, GSS_C_QOP_DEFAULT,
&msg_buf, &cipher_buf);
if (major) {
- CERROR("error wrap: major 0x%x\n", major);
+ CERROR("cred %p: error wrap: major 0x%x\n", cred, major);
GOTO(out, rc = -EINVAL);
}
struct ptlrpcs_wire_hdr *sec_hdr;
rawobj_t cipher_text, plain_text;
__u32 *vp, vlen, subflavor, proc, seq, svc;
- int rc;
+ __u32 major, rc;
ENTRY;
LASSERT(req->rq_repbuf);
vlen -= 5 * 4;
switch (proc) {
- case PTLRPC_GSS_PROC_DATA:
- if (svc != PTLRPC_GSS_SVC_PRIVACY) {
+ case PTLRPCS_GSS_PROC_DATA:
+ if (svc != PTLRPCS_GSS_SVC_PRIVACY) {
CERROR("Unknown svc %d\n", svc);
RETURN(-EPROTO);
}
ctx = gss_cred_get_ctx(cred);
LASSERT(ctx);
- rc = kgss_unwrap(ctx->gc_gss_ctx, GSS_C_QOP_DEFAULT,
- &cipher_text, &plain_text);
- if (rc) {
- CERROR("error unwrap: 0x%x\n", rc);
- GOTO(proc_out, rc = -EINVAL);
+ major = kgss_unwrap(ctx->gc_gss_ctx, GSS_C_QOP_DEFAULT,
+ &cipher_text, &plain_text);
+ if (major) {
+ CERROR("cred %p: error unwrap: major 0x%x\n",
+ cred, major);
+
+ if (major == GSS_S_CREDENTIALS_EXPIRED ||
+ major == GSS_S_CONTEXT_EXPIRED) {
+ ptlrpcs_cred_expire(cred);
+ req->rq_ptlrpcs_restart = 1;
+ rc = 0;
+ } else
+ rc = -EINVAL;
+
+ GOTO(proc_out, rc);
}
req->rq_repmsg = (struct lustre_msg *) vp;
struct ptlrpc_request req;
struct obd_import *imp;
__u32 *vp, lmsg_size;
+ struct ptlrpc_request *raw_req = NULL;
+ const int repbuf_len = 256;
+ char *repbuf;
+ int replen, rc;
ENTRY;
- /* cred's refcount is 0, steal one */
- atomic_inc(&cred->pc_refcount);
-
- gcred = container_of(cred, struct gss_cred, gc_base);
- gcred->gc_ctx->gc_proc = PTLRPC_GSS_PROC_DESTROY;
imp = cred->pc_sec->ps_import;
LASSERT(imp);
- if (!(cred->pc_flags & PTLRPC_CRED_UPTODATE)) {
- CWARN("Destroy a dead gss cred %p(%u@%s), don't send rpc\n",
- gcred, cred->pc_uid, imp->imp_target_uuid.uuid);
- atomic_dec(&cred->pc_refcount);
+ if (test_bit(PTLRPC_CRED_ERROR_BIT, &cred->pc_flags) ||
+ !test_bit(PTLRPC_CRED_UPTODATE_BIT, &cred->pc_flags)) {
+ CDEBUG(D_SEC, "Destroy dead cred %p(%u@%s)\n",
+ cred, cred->pc_uid, imp->imp_target_uuid.uuid);
EXIT;
return;
}
- CWARN("client destroy gss cred %p(%u@%s)\n",
+ might_sleep();
+
+ /* cred's refcount is 0, steal one */
+ atomic_inc(&cred->pc_refcount);
+
+ gcred = container_of(cred, struct gss_cred, gc_base);
+ gcred->gc_ctx->gc_proc = PTLRPCS_GSS_PROC_DESTROY;
+
+ CDEBUG(D_SEC, "client destroy gss cred %p(%u@%s)\n",
gcred, cred->pc_uid, imp->imp_target_uuid.uuid);
lmsg_size = lustre_msg_size(0, NULL);
+ req.rq_req_secflvr = cred->pc_sec->ps_flavor;
+ req.rq_cred = cred;
req.rq_reqbuf_len = sizeof(*hdr) + lmsg_size +
- ptlrpcs_est_req_payload(cred->pc_sec, lmsg_size);
+ ptlrpcs_est_req_payload(&req, lmsg_size);
OBD_ALLOC(req.rq_reqbuf, req.rq_reqbuf_len);
if (!req.rq_reqbuf) {
/* wire hdr */
hdr = buf_to_sec_hdr(req.rq_reqbuf);
- hdr->flavor = cpu_to_le32(PTLRPC_SEC_GSS);
- hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_AUTH);
+ hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_GSS_AUTH);
hdr->msg_len = cpu_to_le32(lmsg_size);
hdr->sec_len = cpu_to_le32(0);
}
atomic_dec(&cred->pc_refcount);
- /* send out */
- gss_send_secfini_rpc(imp, req.rq_reqbuf, req.rq_reqdata_len);
+ OBD_ALLOC(repbuf, repbuf_len);
+ if (!repbuf)
+ goto exit;
+
+ raw_req = ptl_do_rawrpc(imp, req.rq_reqbuf, req.rq_reqbuf_len,
+ req.rq_reqdata_len, repbuf, repbuf_len, &replen,
+ SECFINI_RPC_TIMEOUT, &rc);
+ if (!raw_req)
+ OBD_FREE(repbuf, repbuf_len);
+
exit:
- OBD_FREE(req.rq_reqbuf, req.rq_reqbuf_len);
+ if (raw_req == NULL)
+ OBD_FREE(req.rq_reqbuf, req.rq_reqbuf_len);
+ else
+ rawrpc_req_finished(raw_req);
EXIT;
}
struct vfs_cred vcred = { 0 };
struct ptlrpc_cred *cred;
struct gss_upcall_msg *gss_msg;
+ struct gss_upcall_msg_data gmd = { 0 };
struct gss_cl_ctx *ctx = NULL;
- __u32 dest_ip;
ssize_t left;
int err, gss_err;
ENTRY;
if (left)
GOTO(err_free, err = -EFAULT);
- obj.data = buf;
+ obj.data = (unsigned char *)buf;
obj.len = mlen;
LASSERT(rpci->private);
obdname = import->imp_obd->obd_name;
mech = gsec->gs_mech;
- err = gss_parse_init_downcall(mech, &obj, &ctx, &vcred, &dest_ip,
- &gss_err);
- if (err) {
- CERROR("parse downcall err %d\n", err);
- GOTO(err, err);
- }
+ err = gss_parse_init_downcall(mech, &obj, &ctx, &gmd, &gss_err);
+ if (err)
+ CERROR("parse init downcall err %d\n", err);
+
+ vcred.vc_uid = gmd.gum_uid;
+ vcred.vc_pag = vcred.vc_uid; /* FIXME */
+
cred = ptlrpcs_cred_lookup(sec, &vcred);
if (!cred) {
- CWARN("didn't find cred\n");
- GOTO(err, err);
+ CWARN("didn't find cred for uid %u\n", vcred.vc_uid);
+ GOTO(err, err = -EINVAL);
}
- if (gss_err) {
- CERROR("got gss err %d, set cred %p dead\n", gss_err, cred);
- cred->pc_flags |= PTLRPC_CRED_DEAD;
+
+ if (err || gss_err) {
+ set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags);
+ if (err != -ERESTART || gss_err != 0)
+ set_bit(PTLRPC_CRED_ERROR_BIT, &cred->pc_flags);
+ CERROR("cred %p: rpc err %d, gss err 0x%x, fatal %d\n",
+ cred, err, gss_err,
+ (test_bit(PTLRPC_CRED_ERROR_BIT, &cred->pc_flags) != 0));
} else {
CDEBUG(D_SEC, "get initial ctx:\n");
gss_cred_set_ctx(cred, ctx);
}
spin_lock(&gsec->gs_lock);
- gss_msg = gss_find_upcall(gsec, obdname, vcred.vc_uid, dest_ip);
+ gss_msg = gss_find_upcall(gsec, obdname, &gmd);
if (gss_msg) {
gss_unhash_msg_nolock(gss_msg);
spin_unlock(&gsec->gs_lock);
*********************************************/
static
-struct ptlrpc_sec* gss_create_sec(ptlrpcs_flavor_t *flavor,
+struct ptlrpc_sec* gss_create_sec(__u32 flavor,
const char *pipe_dir,
void *pipe_data)
{
struct ptlrpc_sec *sec;
#ifdef __KERNEL__
char *pos;
+ int pipepath_len;
+ uid_t save_uid;
#endif
ENTRY;
- LASSERT(flavor->flavor == PTLRPC_SEC_GSS);
+ LASSERT(SEC_FLAVOR_MAJOR(flavor) == PTLRPCS_FLVR_MAJOR_GSS);
OBD_ALLOC(gsec, sizeof(*gsec));
if (!gsec) {
RETURN(NULL);
}
- gsec->gs_mech = kgss_subflavor_to_mech(flavor->subflavor);
+ gsec->gs_mech = kgss_subflavor_to_mech(SEC_FLAVOR_SUB(flavor));
if (!gsec->gs_mech) {
- CERROR("subflavor %d not found\n", flavor->subflavor);
+ CERROR("subflavor 0x%x not found\n", flavor);
goto err_free;
}
INIT_LIST_HEAD(&gsec->gs_upcalls);
spin_lock_init(&gsec->gs_lock);
- snprintf(gsec->gs_pipepath, sizeof(gsec->gs_pipepath),
- LUSTRE_PIPEDIR"/%s", pipe_dir);
+ pipepath_len = strlen(LUSTRE_PIPEDIR) + strlen(pipe_dir) +
+ strlen(gsec->gs_mech->gm_name) + 3;
+ OBD_ALLOC(gsec->gs_pipepath, pipepath_len);
+ if (!gsec->gs_pipepath)
+ goto err_mech_put;
+
+ /* pipe rpc require root permission */
+ save_uid = current->fsuid;
+ current->fsuid = 0;
+
+ sprintf(gsec->gs_pipepath, LUSTRE_PIPEDIR"/%s", pipe_dir);
if (IS_ERR(rpc_mkdir(gsec->gs_pipepath, NULL))) {
CERROR("can't make pipedir %s\n", gsec->gs_pipepath);
- goto err_mech_put;
+ goto err_free_path;
}
- snprintf(gsec->gs_pipepath, sizeof(gsec->gs_pipepath),
- LUSTRE_PIPEDIR"/%s/%s", pipe_dir, gsec->gs_mech->gm_name);
+ sprintf(gsec->gs_pipepath, LUSTRE_PIPEDIR"/%s/%s", pipe_dir,
+ gsec->gs_mech->gm_name);
gsec->gs_depipe = rpc_mkpipe(gsec->gs_pipepath, gsec,
&gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
if (IS_ERR(gsec->gs_depipe)) {
#endif
sec = &gsec->gs_base;
-
- switch (flavor->subflavor) {
- case PTLRPC_SEC_GSS_KRB5I:
- sec->ps_sectype = PTLRPC_SEC_TYPE_AUTH;
- break;
- case PTLRPC_SEC_GSS_KRB5P:
- sec->ps_sectype = PTLRPC_SEC_TYPE_PRIV;
- break;
- default:
- LBUG();
- }
-
sec->ps_expire = GSS_CREDCACHE_EXPIRE;
sec->ps_nextgc = get_seconds() + sec->ps_expire;
sec->ps_flags = 0;
+ current->fsuid = save_uid;
+
CDEBUG(D_SEC, "Create GSS security instance at %p(external %p)\n",
gsec, sec);
RETURN(sec);
LASSERT(pos);
*pos = 0;
rpc_rmdir(gsec->gs_pipepath);
+err_free_path:
+ current->fsuid = save_uid;
+ OBD_FREE(gsec->gs_pipepath, pipepath_len);
err_mech_put:
#endif
kgss_mech_put(gsec->gs_mech);
struct gss_sec *gsec;
#ifdef __KERNEL__
char *pos;
+ int pipepath_len;
#endif
ENTRY;
LASSERT(!atomic_read(&sec->ps_refcount));
LASSERT(!atomic_read(&sec->ps_credcount));
#ifdef __KERNEL__
+ pipepath_len = strlen(gsec->gs_pipepath) + 1;
rpc_unlink(gsec->gs_pipepath);
pos = strrchr(gsec->gs_pipepath, '/');
LASSERT(pos);
*pos = 0;
rpc_rmdir(gsec->gs_pipepath);
+ OBD_FREE(gsec->gs_pipepath, pipepath_len);
#endif
kgss_mech_put(gsec->gs_mech);
static
struct ptlrpc_cred * gss_create_cred(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
struct vfs_cred *vcred)
{
struct gss_cred *gcred;
atomic_set(&cred->pc_refcount, 0);
cred->pc_sec = sec;
cred->pc_ops = &gss_credops;
- cred->pc_req = req;
- cred->pc_expire = get_seconds() + GSS_CRED_EXPIRE;
+ cred->pc_expire = 0;
cred->pc_flags = 0;
cred->pc_pag = vcred->vc_pag;
cred->pc_uid = vcred->vc_uid;
RETURN(cred);
}
-static int gss_estimate_payload(struct ptlrpc_sec *sec, int msgsize)
+static int gss_estimate_payload(struct ptlrpc_sec *sec,
+ struct ptlrpc_request *req,
+ int msgsize)
{
- switch (sec->ps_sectype) {
- case PTLRPC_SEC_TYPE_AUTH:
+ switch (SEC_FLAVOR_SVC(req->rq_req_secflvr)) {
+ case PTLRPCS_SVC_AUTH:
return GSS_MAX_AUTH_PAYLOAD;
- case PTLRPC_SEC_TYPE_PRIV:
+ case PTLRPCS_SVC_PRIV:
return size_round16(GSS_MAX_AUTH_PAYLOAD + msgsize +
GSS_PRIVBUF_PREFIX_LEN +
GSS_PRIVBUF_SUFFIX_LEN);
/* In PRIVACY mode, lustre message is always 0 (already encoded into
* security payload).
*/
- privacy = sec->ps_sectype == PTLRPC_SEC_TYPE_PRIV;
+ privacy = (SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_PRIV);
msg_payload = privacy ? 0 : lmsg_size;
- sec_payload = gss_estimate_payload(sec, lmsg_size);
+ sec_payload = gss_estimate_payload(sec, req, lmsg_size);
rc = sec_alloc_reqbuf(sec, req, msg_payload, sec_payload);
if (rc)
LASSERT(req->rq_reqmsg);
LASSERT(req->rq_reqlen);
- privacy = sec->ps_sectype == PTLRPC_SEC_TYPE_PRIV;
+ privacy = SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_PRIV;
if (privacy) {
buf = (char *) req->rq_reqmsg - GSS_PRIVBUF_PREFIX_LEN;
LASSERT(buf < req->rq_reqbuf ||
static struct ptlrpc_sec_type gss_type = {
.pst_owner = THIS_MODULE,
- .pst_name = "GSS_SEC",
+ .pst_name = "sec.gss",
.pst_inst = ATOMIC_INIT(0),
- .pst_flavor = {PTLRPC_SEC_GSS, 0},
+ .pst_flavor = PTLRPCS_FLVR_MAJOR_GSS,
.pst_ops = &gss_secops,
};