X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fgss%2Fgss_cli_upcall.c;h=eb9536b96a0546bf80e31820dc6b69e6893f4527;hb=aa145aa1fdfab120acd3de5cf5af067d9ca516f6;hp=fed7c482f0cd389a9ff67505b1de6ea010deb8c7;hpb=ff3662c58323f7f4aac2fde07c2ed2c940ad0331;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/gss/gss_cli_upcall.c b/lustre/ptlrpc/gss/gss_cli_upcall.c index fed7c48..eb9536b 100644 --- a/lustre/ptlrpc/gss/gss_cli_upcall.c +++ b/lustre/ptlrpc/gss/gss_cli_upcall.c @@ -1,27 +1,41 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Copyright (C) 2006 Cluster File Systems, Inc. - * Author: Eric Mei + * GPL HEADER START * - * This file is part of the Lustre file system, http://www.lustre.org - * Lustre is a trademark of Cluster File Systems, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * You may have signed or agreed to another license before downloading - * this software. If so, you are bound by the terms and conditions - * of that agreement, and the following does not apply to you. See the - * LICENSE file included with this distribution for more information. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * If you did not agree to a different license, then this copy of Lustre - * is open source software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * In either case, Lustre is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * license text for more details. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/ptlrpc/gss/gss_cli_upcall.c + * + * Author: Eric Mei */ #ifndef EXPORT_SYMTAB @@ -35,7 +49,6 @@ #include #include #include -#include #else #include #endif @@ -72,10 +85,13 @@ 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)); ghdr->gh_version = PTLRPC_GSS_VERSION; + ghdr->gh_sp = (__u8) imp->imp_sec->ps_part; ghdr->gh_flags = 0; ghdr->gh_proc = PTLRPC_GSS_PROC_INIT; ghdr->gh_seq = 0; @@ -83,7 +99,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 +114,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); @@ -110,7 +129,7 @@ int ctx_init_pack_request(struct obd_import *imp, /* 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); + 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)) @@ -119,11 +138,11 @@ int ctx_init_pack_request(struct obd_import *imp, /* 4. now the token */ LASSERT(size >= (sizeof(__u32) + token_size)); *p++ = cpu_to_le32(((__u32) token_size)); - if (copy_from_user(p, token, token_size)) { + if (cfs_copy_from_user(p, token, token_size)) { CERROR("can't copy token\n"); return -EFAULT; } - size -= sizeof(__u32) + size_round4(token_size); + size -= sizeof(__u32) + cfs_size_round4(token_size); req->rq_reqdata_len = lustre_shrink_msg(req->rq_reqbuf, offset, msg->lm_buflens[offset] - size, 0); @@ -131,7 +150,7 @@ int ctx_init_pack_request(struct obd_import *imp, } static -int ctx_init_parse_reply(struct lustre_msg *msg, +int ctx_init_parse_reply(struct lustre_msg *msg, int swabbed, char __user *outbuf, long outlen) { struct gss_rep_header *ghdr; @@ -143,7 +162,7 @@ int ctx_init_parse_reply(struct lustre_msg *msg, return -EPROTO; } - ghdr = (struct gss_rep_header *) gss_swab_header(msg, 0); + ghdr = (struct gss_rep_header *) gss_swab_header(msg, 0, swabbed); if (ghdr == NULL) { CERROR("unable to extract gss reply header\n"); return -EPROTO; @@ -154,8 +173,8 @@ int ctx_init_parse_reply(struct lustre_msg *msg, return -EPROTO; } - if (outlen < (4 + 2) * 4 + size_round4(ghdr->gh_handle.len) + - size_round4(msg->lm_buflens[2])) { + if (outlen < (4 + 2) * 4 + cfs_size_round4(ghdr->gh_handle.len) + + cfs_size_round4(msg->lm_buflens[2])) { CERROR("output buffer size %ld too small\n", outlen); return -EFAULT; } @@ -163,16 +182,16 @@ int ctx_init_parse_reply(struct lustre_msg *msg, status = 0; effective = 0; - if (copy_to_user(outbuf, &status, 4)) + if (cfs_copy_to_user(outbuf, &status, 4)) return -EFAULT; outbuf += 4; - if (copy_to_user(outbuf, &ghdr->gh_major, 4)) + if (cfs_copy_to_user(outbuf, &ghdr->gh_major, 4)) return -EFAULT; outbuf += 4; - if (copy_to_user(outbuf, &ghdr->gh_minor, 4)) + if (cfs_copy_to_user(outbuf, &ghdr->gh_minor, 4)) return -EFAULT; outbuf += 4; - if (copy_to_user(outbuf, &ghdr->gh_seqwin, 4)) + if (cfs_copy_to_user(outbuf, &ghdr->gh_seqwin, 4)) return -EFAULT; outbuf += 4; effective += 4 * 4; @@ -180,10 +199,10 @@ int ctx_init_parse_reply(struct lustre_msg *msg, /* handle */ obj_len = ghdr->gh_handle.len; round_len = (obj_len + 3) & ~ 3; - if (copy_to_user(outbuf, &obj_len, 4)) + if (cfs_copy_to_user(outbuf, &obj_len, 4)) return -EFAULT; outbuf += 4; - if (copy_to_user(outbuf, (char *) ghdr->gh_handle.data, round_len)) + if (cfs_copy_to_user(outbuf, (char *) ghdr->gh_handle.data, round_len)) return -EFAULT; outbuf += round_len; effective += 4 + round_len; @@ -191,10 +210,10 @@ int ctx_init_parse_reply(struct lustre_msg *msg, /* out token */ obj_len = msg->lm_buflens[2]; round_len = (obj_len + 3) & ~ 3; - if (copy_to_user(outbuf, &obj_len, 4)) + if (cfs_copy_to_user(outbuf, &obj_len, 4)) return -EFAULT; outbuf += 4; - if (copy_to_user(outbuf, lustre_msg_buf(msg, 2, 0), round_len)) + if (cfs_copy_to_user(outbuf, lustre_msg_buf(msg, 2, 0), round_len)) return -EFAULT; outbuf += round_len; effective += 4 + round_len; @@ -205,6 +224,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 */ @@ -225,15 +245,14 @@ 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)) { - CERROR("ioctl size %lu, expect %lu, please check lgssd version\n", - count, (unsigned long) sizeof(param)); + CERROR("ioctl size %lu, expect %lu, please check lgss_keyring " + "version\n", count, (unsigned long) sizeof(param)); RETURN(-EINVAL); } - if (copy_from_user(¶m, buffer, sizeof(param))) { + if (cfs_copy_from_user(¶m, buffer, sizeof(param))) { CERROR("failed copy data from lgssd\n"); RETURN(-EFAULT); } @@ -256,19 +275,56 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count) RETURN(-EINVAL); } + if (unlikely(!obd->obd_set_up)) { + CERROR("obd %s not setup\n", obdname); + RETURN(-EINVAL); + } + + cfs_spin_lock(&obd->obd_dev_lock); + if (obd->obd_stopping) { + CERROR("obd %s has stopped\n", obdname); + cfs_spin_unlock(&obd->obd_dev_lock); + RETURN(-EINVAL); + } + + if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) && + strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) && + strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) { + CERROR("obd %s is not a client device\n", obdname); + cfs_spin_unlock(&obd->obd_dev_lock); + RETURN(-EINVAL); + } + cfs_spin_unlock(&obd->obd_dev_lock); + + cfs_down_read(&obd->u.cli.cl_sem); + if (obd->u.cli.cl_import == NULL) { + CERROR("obd %s: import has gone\n", obd->obd_name); + RETURN(-EINVAL); + } imp = class_import_get(obd->u.cli.cl_import); - LASSERT(imp->imp_sec); + cfs_up_read(&obd->u.cli.cl_sem); - /* force this import to use v2 msg */ - imp->imp_msg_magic = LUSTRE_MSG_MAGIC_V2; + if (imp->imp_deactive) { + CERROR("import has been deactivated\n"); + class_import_put(imp); + RETURN(-EINVAL); + } - 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, @@ -280,7 +336,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) { @@ -298,7 +354,9 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count) goto out_copy; } - lsize = ctx_init_parse_reply(req->rq_repbuf, + LASSERT(req->rq_repdata); + lsize = ctx_init_parse_reply(req->rq_repdata, + ptlrpc_rep_need_swab(req), param.reply_buf, param.reply_buf_size); if (lsize < 0) { param.status = (int) lsize; @@ -309,7 +367,7 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count) param.reply_length = lsize; out_copy: - if (copy_to_user(buffer, ¶m, sizeof(param))) + if (cfs_copy_to_user(buffer, ¶m, sizeof(param))) rc = -EFAULT; else rc = 0; @@ -325,11 +383,10 @@ 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); + LASSERT(cfs_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, " @@ -338,25 +395,32 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx) RETURN(0); } - might_sleep(); + cfs_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)); + 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, 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. */ pud = lustre_msg_buf(req->rq_reqbuf, 2, sizeof(*pud)); @@ -369,12 +433,11 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx) req->rq_phase = RQ_PHASE_RPC; rc = ptl_send_rpc(req, 1); - if (rc) { - CWARN("ctx %p(%u->%s): rpc error %d, destroy locally\n", - ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec), - rc); - } + if (rc) + CWARN("ctx %p(%u->%s): rpc error %d, destroy locally\n", ctx, + ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec), rc); +out_ref: ptlrpc_req_finished(req); out: RETURN(rc);