Whamcloud - gitweb
b=14149
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_cli_upcall.c
index e36a092..da435a5 100644 (file)
@@ -72,6 +72,8 @@ int ctx_init_pack_request(struct obd_import *imp,
         rawobj_t                 obj;
 
         LASSERT(msg->lm_bufcount <= 4);
+        LASSERT(req->rq_cli_ctx);
+        LASSERT(req->rq_cli_ctx->cc_sec);
 
         /* gss hdr */
         ghdr = lustre_msg_buf(msg, 0, sizeof(*ghdr));
@@ -83,7 +85,9 @@ int ctx_init_pack_request(struct obd_import *imp,
         ghdr->gh_handle.len = 0;
 
         /* fix the user desc */
-        if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
+        if (req->rq_pack_udesc) {
+                ghdr->gh_flags |= LUSTRE_GSS_PACK_USER;
+
                 pud = lustre_msg_buf(msg, offset, sizeof(*pud));
                 LASSERT(pud);
                 pud->pud_uid = pud->pud_fsuid = uid;
@@ -96,6 +100,7 @@ int ctx_init_pack_request(struct obd_import *imp,
         /* security payload */
         p = lustre_msg_buf(msg, offset, 0);
         size = msg->lm_buflens[offset];
+        LASSERT(p);
 
         /* 1. lustre svc type */
         LASSERT(size > 4);
@@ -109,9 +114,8 @@ int ctx_init_pack_request(struct obd_import *imp,
                 LBUG();
 
         /* 3. reverse context handle. actually only needed by root user,
-         *    but we send it anyway.
-         */
-        gsec = container_of(imp->imp_sec, struct gss_sec, gs_base);
+         *    but we send it anyway. */
+        gsec = sec2gsec(req->rq_cli_ctx->cc_sec);
         obj.len = sizeof(gsec->gs_rvs_hdl);
         obj.data = (__u8 *) &gsec->gs_rvs_hdl;
         if (rawobj_serialize(&obj, &p, &size))
@@ -206,6 +210,7 @@ int ctx_init_parse_reply(struct lustre_msg *msg,
 /* XXX move to where lgssd could see */
 struct lgssd_ioctl_param {
         int             version;        /* in   */
+        int             secid;          /* in   */
         char           *uuid;           /* in   */
         int             lustre_svc;     /* in   */
         uid_t           uid;            /* in   */
@@ -226,7 +231,6 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
         struct obd_device        *obd;
         char                      obdname[64];
         long                      lsize;
-        int                       lmsg_size = sizeof(struct ptlrpc_body);
         int                       rc;
 
         if (count != sizeof(param)) {
@@ -263,13 +267,21 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
         /* force this import to use v2 msg */
         imp->imp_msg_magic = LUSTRE_MSG_MAGIC_V2;
 
-        req = ptlrpc_prep_req(imp, LUSTRE_OBD_VERSION, SEC_CTX_INIT,
-                              1, &lmsg_size, NULL);
-        if (!req) {
+        req = ptlrpc_request_alloc_pack(imp, &RQF_SEC_CTX, LUSTRE_OBD_VERSION,
+                                        SEC_CTX_INIT);
+        if (req == NULL) {
                 param.status = -ENOMEM;
                 goto out_copy;
         }
 
+        if (req->rq_cli_ctx->cc_sec->ps_id != param.secid) {
+                CWARN("original secid %d, now has changed to %d, "
+                      "cancel this negotiation\n", param.secid,
+                      req->rq_cli_ctx->cc_sec->ps_id);
+                param.status = -EINVAL;
+                goto out_copy;
+        }
+
         /* get token */
         rc = ctx_init_pack_request(imp, req,
                                    param.lustre_svc,
@@ -281,7 +293,7 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
                 goto out_copy;
         }
 
-        req->rq_replen = lustre_msg_size_v2(1, &lmsg_size);
+        ptlrpc_request_set_replen(req);
 
         rc = ptlrpc_queue_wait(req);
         if (rc) {
@@ -292,8 +304,7 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
                  * leave recovery decisions to general ptlrpc layer.
                  *
                  * FIXME maybe some other error code shouldn't be treated
-                 * as timeout.
-                 */
+                 * as timeout. */
                 param.status = rc;
                 if (rc != -EACCES)
                         param.status = -ETIMEDOUT;
@@ -327,10 +338,11 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
         struct obd_import       *imp = ctx->cc_sec->ps_import;
         struct ptlrpc_request   *req;
         struct ptlrpc_user_desc *pud;
-        int                      buflens = sizeof(struct ptlrpc_body);
         int                      rc;
         ENTRY;
 
+        LASSERT(atomic_read(&ctx->cc_refcount) > 0);
+
         if (cli_ctx_is_error(ctx) || !cli_ctx_is_uptodate(ctx)) {
                 CDEBUG(D_SEC, "ctx %p(%u->%s) not uptodate, "
                        "don't send destroy rpc\n", ctx,
@@ -340,29 +352,32 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
 
         might_sleep();
 
-        CDEBUG(D_SEC, "%s ctx %p(%u->%s)\n",
-               sec_is_reverse(ctx->cc_sec) ?
-               "server finishing reverse" : "client finishing forward",
-               ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
-
-        /* context's refcount could be 0, steal one */
-        atomic_inc(&ctx->cc_refcount);
+        CWARN("%s ctx %p idx "LPX64" (%u->%s)\n",
+              sec_is_reverse(ctx->cc_sec) ?
+              "server finishing reverse" : "client finishing forward",
+              ctx, gss_handle_to_u64(&gctx->gc_handle),
+              ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
 
         gctx->gc_proc = PTLRPC_GSS_PROC_DESTROY;
 
-        req = ptlrpc_prep_req_pool(imp, LUSTRE_OBD_VERSION, SEC_CTX_FINI,
-                                   1, &buflens, NULL, NULL, ctx);
-        if (!req) {
+        req = ptlrpc_request_alloc(imp, &RQF_SEC_CTX);
+        if (req == NULL) {
                 CWARN("ctx %p(%u): fail to prepare rpc, destroy locally\n",
                       ctx, ctx->cc_vcred.vc_uid);
-                GOTO(out_ref, rc = -ENOMEM);
+                GOTO(out, rc = -ENOMEM);
+        }
+
+        rc = ptlrpc_request_bufs_pack(req, LUSTRE_OBD_VERSION, SEC_CTX_FINI,
+                                      NULL, ctx);
+        if (rc) {
+                ptlrpc_request_free(req);
+                GOTO(out_ref, rc);
         }
 
         /* fix the user desc */
-        if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
+        if (req->rq_pack_udesc) {
                 /* we rely the fact that this request is in AUTH mode,
-                 * and user_desc at offset 2.
-                 */
+                 * and user_desc at offset 2. */
                 pud = lustre_msg_buf(req->rq_reqbuf, 2, sizeof(*pud));
                 LASSERT(pud);
                 pud->pud_uid = pud->pud_fsuid = ctx->cc_vcred.vc_uid;
@@ -380,8 +395,7 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
         }
 
         ptlrpc_req_finished(req);
-out_ref:
-        atomic_dec(&ctx->cc_refcount);
+out:
         RETURN(rc);
 }