From e163b538998aa0668334336b109860ccba4e1b7f Mon Sep 17 00:00:00 2001 From: ericm Date: Fri, 3 Nov 2006 21:06:07 +0000 Subject: [PATCH] branch: b_new_cmd after negotiation handling might invalidate the whole negotiation, do proper cleanup, and client don't repeatedly try (bug found by fanyong). --- lustre/include/lustre_sec.h | 3 +++ lustre/mdt/mdt_handler.c | 15 ++++++++++++++- lustre/ptlrpc/gss/gss_cli_upcall.c | 15 ++++++++++----- lustre/ptlrpc/gss/sec_gss.c | 21 +++++++++++++++++++++ lustre/ptlrpc/sec.c | 13 +++++++++++++ 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index bdfe6bc..bf91616 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -312,6 +312,8 @@ struct ptlrpc_sec_cops { struct ptlrpc_sec_sops { int (*accept) (struct ptlrpc_request *req); int (*authorize) (struct ptlrpc_request *req); + void (*invalidate_ctx) + (struct ptlrpc_svc_ctx *ctx); /* buffer manipulation */ int (*alloc_rs) (struct ptlrpc_request *req, int msgsize); @@ -525,6 +527,7 @@ int sptlrpc_svc_wrap_reply(struct ptlrpc_request *req); void sptlrpc_svc_free_rs(struct ptlrpc_reply_state *rs); void sptlrpc_svc_ctx_addref(struct ptlrpc_request *req); void sptlrpc_svc_ctx_decref(struct ptlrpc_request *req); +void sptlrpc_svc_ctx_invalidate(struct ptlrpc_request *req); /* * reverse context diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index d8eb646..78424b6 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -1546,7 +1546,20 @@ static int mdt_cp_callback(struct mdt_thread_info *info) */ static int mdt_sec_ctx_handle(struct mdt_thread_info *info) { - return mdt_handle_idmap(info); + int rc; + + rc = mdt_handle_idmap(info); + + if (unlikely(rc)) { + struct ptlrpc_request *req = mdt_info_req(info); + __u32 opc; + + opc = lustre_msg_get_opc(req->rq_reqmsg); + if (opc = SEC_CTX_INIT || opc == SEC_CTX_INIT_CONT) + sptlrpc_svc_ctx_invalidate(req); + } + + return rc; } static struct mdt_object *mdt_obj(struct lu_object *o) diff --git a/lustre/ptlrpc/gss/gss_cli_upcall.c b/lustre/ptlrpc/gss/gss_cli_upcall.c index a67b297..c20129f 100644 --- a/lustre/ptlrpc/gss/gss_cli_upcall.c +++ b/lustre/ptlrpc/gss/gss_cli_upcall.c @@ -856,12 +856,17 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count) rc = ptlrpc_queue_wait(req); if (rc) { /* If any _real_ denial be made, we expect server return - * error reply instead of simply drop request. So here - * all errors during networking just be treat as TIMEDOUT, - * caller might re-try negotiation again and again, leave - * recovery decisions to general ptlrpc layer. + * -EACCES reply or return success but indicate gss error + * inside reply messsage. All other errors are treated as + * timeout, caller might try the negotiation repeatedly, + * leave recovery decisions to general ptlrpc layer. + * + * FIXME maybe some other error code shouldn't be treated + * as timeout. */ - param.status = -ETIMEDOUT; + param.status = rc; + if (rc != -EACCES) + param.status = -ETIMEDOUT; goto out_copy; } diff --git a/lustre/ptlrpc/gss/sec_gss.c b/lustre/ptlrpc/gss/sec_gss.c index 13d8d20..a12e17b 100644 --- a/lustre/ptlrpc/gss/sec_gss.c +++ b/lustre/ptlrpc/gss/sec_gss.c @@ -2231,6 +2231,26 @@ int gss_svc_accept(struct ptlrpc_request *req) RETURN(rc); } +static +void gss_svc_invalidate_ctx(struct ptlrpc_svc_ctx *svc_ctx) +{ + struct gss_svc_reqctx *grctx; + ENTRY; + + if (svc_ctx == NULL) { + EXIT; + return; + } + + grctx = gss_svc_ctx2reqctx(svc_ctx); + + CWARN("gss svc invalidate ctx %p(%u)\n", + grctx->src_ctx, grctx->src_ctx->gsc_uid); + gss_svc_upcall_destroy_ctx(grctx->src_ctx); + + EXIT; +} + static inline int gss_svc_payload(struct gss_svc_reqctx *grctx, int msgsize, int privacy) { @@ -2515,6 +2535,7 @@ int gss_svc_install_rctx(struct obd_import *imp, struct ptlrpc_svc_ctx *ctx) static struct ptlrpc_sec_sops gss_sec_sops = { .accept = gss_svc_accept, + .invalidate_ctx = gss_svc_invalidate_ctx, .alloc_rs = gss_svc_alloc_rs, .authorize = gss_svc_authorize, .free_rs = gss_svc_free_rs, diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index 4332e51..d57144f 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -1705,6 +1705,19 @@ void sptlrpc_svc_ctx_decref(struct ptlrpc_request *req) req->rq_svc_ctx = NULL; } +void sptlrpc_svc_ctx_invalidate(struct ptlrpc_request *req) +{ + struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx; + + if (ctx == NULL) + return; + + LASSERT(atomic_read(&ctx->sc_refcount) > 0); + if (ctx->sc_policy->sp_sops->invalidate_ctx) + ctx->sc_policy->sp_sops->invalidate_ctx(ctx); +} +EXPORT_SYMBOL(sptlrpc_svc_ctx_invalidate); + /**************************************** * bulk security * ****************************************/ -- 1.8.3.1