#include "gss_internal.h"
#include "gss_api.h"
-#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"
+#define GSS_CREDCACHE_EXPIRE (30 * 60) /* 30 minute */
+
/**********************************************
* gss security init/fini helper *
**********************************************/
-#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,
p = (__u32 *) buf_to_sec_data(repbuf);
effective = 0;
- status = le32_to_cpu(*p++);
+ p += 2; /* skip the leading unused bytes */
+ seq = le32_to_cpu(*p++);
major = le32_to_cpu(*p++);
minor = le32_to_cpu(*p++);
- seq = le32_to_cpu(*p++);
+ status = 0;
+
effective += 4 * 4;
if (copy_to_user(outbuf, &status, 4))
struct gss_sec {
struct ptlrpc_sec gs_base;
struct gss_api_mech *gs_mech;
-#ifdef __KERNEL__
spinlock_t gs_lock;
struct list_head gs_upcalls;
char *gs_pipepath;
struct dentry *gs_depipe;
-#endif
};
-#ifdef __KERNEL__
-
-static rwlock_t gss_ctx_lock = RW_LOCK_UNLOCKED;
-
struct gss_upcall_msg_data {
+ __u64 gum_pag;
__u32 gum_uid;
__u32 gum_svc;
__u32 gum_nal;
struct gss_upcall_msg_data gum_data;
};
+#ifdef __KERNEL__
+static rwlock_t gss_ctx_lock = RW_LOCK_UNLOCKED;
/**********************************************
* rpc_pipe upcall helpers *
**********************************************/
return;
}
LASSERT(list_empty(&gmsg->gum_list));
+#if 0
LASSERT(list_empty(&gmsg->gum_base.list));
+#else
+ /* XXX */
+ if (!list_empty(&gmsg->gum_base.list)) {
+ int error = gmsg->gum_base.errno;
+
+ CWARN("msg %p: list: %p/%p/%p, copied %d, err %d, wq %d\n",
+ gmsg, &gmsg->gum_base.list, gmsg->gum_base.list.prev,
+ gmsg->gum_base.list.next, gmsg->gum_base.copied, error,
+ list_empty(&gmsg->gum_waitq.task_list));
+ LBUG();
+ }
+#endif
OBD_FREE(gmsg, sizeof(*gmsg));
EXIT;
}
static void
gss_unhash_msg_nolock(struct gss_upcall_msg *gmsg)
{
- ENTRY;
- if (list_empty(&gmsg->gum_list)) {
- EXIT;
+ LASSERT_SPIN_LOCKED(&gmsg->gum_gsec->gs_lock);
+
+ if (list_empty(&gmsg->gum_list))
return;
- }
list_del_init(&gmsg->gum_list);
wake_up(&gmsg->gum_waitq);
+ LASSERT(atomic_read(&gmsg->gum_refcount) > 1);
atomic_dec(&gmsg->gum_refcount);
- CDEBUG(D_SEC, "gmsg %p refcount now %d\n",
- gmsg, atomic_read(&gmsg->gum_refcount));
- LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
- EXIT;
}
static void
struct gss_upcall_msg *gmsg;
ENTRY;
+ LASSERT_SPIN_LOCKED(&gsec->gs_lock);
+
list_for_each_entry(gmsg, &gsec->gs_upcalls, gum_list) {
if (memcmp(&gmsg->gum_data, gmd, sizeof(*gmd)))
continue;
if (strcmp(gmsg->gum_obdname, obdname))
continue;
+ LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
atomic_inc(&gmsg->gum_refcount);
CDEBUG(D_SEC, "found gmsg at %p: obdname %s, uid %d, ref %d\n",
gmsg, obdname, gmd->gum_uid,
memcpy(&gmsg->gum_data, gmd, sizeof(*gmd));
rpcmsg = &gmsg->gum_base;
+ INIT_LIST_HEAD(&rpcmsg->list);
rpcmsg->data = &gmsg->gum_data;
rpcmsg->len = sizeof(gmsg->gum_data);
+ rpcmsg->copied = 0;
+ rpcmsg->errno = 0;
EXIT;
}
#endif /* __KERNEL__ */
+/* this seems to be used only from userspace code */
+#ifndef __KERNEL__
/********************************************
* gss cred manipulation helpers *
********************************************/
-#if 0
static
int gss_cred_is_uptodate_ctx(struct ptlrpc_cred *cred)
{
#endif
static inline
-struct gss_cl_ctx * gss_get_ctx(struct gss_cl_ctx *ctx)
+struct gss_cl_ctx *gss_get_ctx(struct gss_cl_ctx *ctx)
{
atomic_inc(&ctx->gc_refcount);
return ctx;
CERROR("unable to get expire time\n");
ctx_expiry = 1; /* make it expired now */
}
- cred->pc_expire = (unsigned long) ctx_expiry;
+ cred->pc_expire = gss_roundup_expire_time(ctx_expiry);
write_lock(&gss_ctx_lock);
old = gcred->gc_ctx;
spin_lock_init(&ctx->gc_seq_lock);
atomic_set(&ctx->gc_refcount,1);
+ if (simple_get_bytes(&p, &len, &gmd->gum_pag, sizeof(gmd->gum_pag)))
+ goto err_free_ctx;
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)))
* cred APIs *
***************************************/
#ifdef __KERNEL__
-#define CRED_REFRESH_UPCALL_TIMEOUT (50)
static int gss_cred_refresh(struct ptlrpc_cred *cred)
{
struct obd_import *import;
struct dentry *dentry;
char *obdname, *obdtype;
wait_queue_t wait;
- uid_t uid = cred->pc_uid;
int res;
ENTRY;
RETURN(-EINVAL);
}
- gmd.gum_uid = uid;
+ gmd.gum_pag = cred->pc_pag;
+ gmd.gum_uid = cred->pc_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"))
+ if (!strcmp(obdtype, OBD_MDC_DEVICENAME))
gmd.gum_svc = LUSTRE_GSS_SVC_MDS;
- else if (!strcmp(obdtype, "osc"))
+ else if (!strcmp(obdtype, OBD_OSC_DEVICENAME))
gmd.gum_svc = LUSTRE_GSS_SVC_OSS;
else {
CERROR("gss on %s?\n", obdtype);
CDEBUG(D_SEC, "Initiate gss context %p(%u@%s)\n",
container_of(cred, struct gss_cred, gc_base),
- uid, import->imp_target_uuid.uuid);
+ cred->pc_uid, import->imp_target_uuid.uuid);
again:
spin_lock(&gsec->gs_lock);
}
#else /* !__KERNEL__ */
extern int lgss_handle_krb5_upcall(uid_t uid, __u32 dest_ip,
- char *obd_name,
- char *buf, int bufsize,
+ char *obd_name, char *buf, int bufsize,
int (*callback)(char*, unsigned long));
static int gss_cred_refresh(struct ptlrpc_cred *cred)
struct gss_sec *gsec;
struct gss_api_mech *mech;
struct gss_cl_ctx *ctx = NULL;
- struct vfs_cred vcred = { 0 };
ptl_nid_t peer_nid;
__u32 dest_ip;
__u32 subflavor;
int rc, gss_err;
+ struct gss_upcall_msg_data gmd = { 0 };
LASSERT(cred);
LASSERT(cred->pc_sec);
imp = cred->pc_sec->ps_import;
peer_nid = imp->imp_connection->c_peer.peer_id.nid;
dest_ip = (__u32) (peer_nid & 0xFFFFFFFF);
- subflavor = cred->pc_sec->ps_flavor.subflavor;
+ subflavor = cred->pc_sec->ps_flavor;
- if (subflavor != PTLRPC_SEC_GSS_KRB5I) {
+ if (subflavor != PTLRPCS_SUBFLVR_KRB5I) {
CERROR("unknown subflavor %u\n", subflavor);
GOTO(err_out, rc = -EINVAL);
}
gsec = container_of(cred->pc_sec, struct gss_sec, gs_base);
mech = gsec->gs_mech;
LASSERT(mech);
- rc = gss_parse_init_downcall(mech, &obj, &ctx, &vcred, &dest_ip,
+
+ rc = gss_parse_init_downcall(mech, &obj, &ctx, &gmd,
&gss_err);
if (rc || gss_err) {
CERROR("parse init downcall: rpc %d, gss 0x%x\n", rc, gss_err);
*/
if (major == GSS_S_NO_CONTEXT ||
major == GSS_S_BAD_SIG) {
- CWARN("req %p: server report cred %p %s, expired?\n",
+ CWARN("req %p: server report cred %p %s\n",
req, cred, (major == GSS_S_NO_CONTEXT) ?
"NO_CONTEXT" : "BAD_SIG");
gss_put_ctx(gcred->gc_ctx);
}
- CDEBUG(D_SEC, "GSS_SEC: destroy cred %p\n", gcred);
+ CDEBUG(D_SEC, "sec.gss %p: destroy cred %p\n", cred->pc_sec, gcred);
OBD_FREE(gcred, sizeof(*gcred));
EXIT;
if (err)
CERROR("parse init downcall err %d\n", err);
+ vcred.vc_pag = gmd.gum_pag;
vcred.vc_uid = gmd.gum_uid;
- vcred.vc_pag = vcred.vc_uid; /* FIXME */
cred = ptlrpcs_cred_lookup(sec, &vcred);
if (!cred) {
static unsigned long ratelimit;
ENTRY;
+ LASSERT(list_empty(&msg->list));
+
if (msg->errno >= 0) {
EXIT;
return;
gmsg = container_of(msg, struct gss_upcall_msg, gum_base);
CDEBUG(D_SEC, "destroy gmsg %p\n", gmsg);
+ LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
atomic_inc(&gmsg->gum_refcount);
gss_unhash_msg(gmsg);
if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) {
unsigned long now = get_seconds();
if (time_after(now, ratelimit)) {
- CWARN("GSS_SEC upcall timed out.\n"
+ CWARN("sec.gss upcall timed out.\n"
"Please check user daemon is running!\n");
ratelimit = now + 15;
}
gmsg = list_entry(gsec->gs_upcalls.next,
struct gss_upcall_msg, gum_list);
+ LASSERT(list_empty(&gmsg->gum_base.list));
gmsg->gum_base.errno = -EPIPE;
atomic_inc(&gmsg->gum_refcount);
gss_unhash_msg_nolock(gmsg);
{
struct gss_sec *gsec;
struct ptlrpc_sec *sec;
+ uid_t save_uid;
+
#ifdef __KERNEL__
char *pos;
int pipepath_len;
- uid_t save_uid;
#endif
ENTRY;
current->fsuid = save_uid;
- CDEBUG(D_SEC, "Create GSS security instance at %p(external %p)\n",
- gsec, sec);
+ CDEBUG(D_SEC, "Create sec.gss %p\n", gsec);
RETURN(sec);
#ifdef __KERNEL__
ENTRY;
gsec = container_of(sec, struct gss_sec, gs_base);
- CDEBUG(D_SEC, "Destroy GSS security instance at %p\n", gsec);
+ CDEBUG(D_SEC, "Destroy sec.gss %p\n", gsec);
LASSERT(gsec->gs_mech);
LASSERT(!atomic_read(&sec->ps_refcount));