mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-08 02:21:18 +00:00
staging: lustre: ptlrpc: gss: delete unused code
The gss code has never been built, there is no Kconfig option for it, so delete it as code that can not build goes bad really fast. If someone wants it back, they can revert this and fix any build errors that might be in it. Cc: Andreas Dilger <andreas.dilger@intel.com> Cc: Oleg Drokin <oleg.drokin@intel.com> Cc: hpdd-discuss <hpdd-discuss@lists.01.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e27db14919
commit
b78560200d
@ -18,5 +18,3 @@ ptlrpc_objs += sec_null.o sec_plain.o nrs.o nrs_fifo.o
|
||||
ptlrpc-y := $(ldlm_objs) $(ptlrpc_objs)
|
||||
ptlrpc-$(CONFIG_PROC_FS) += sec_lproc.o
|
||||
ptlrpc-$(CONFIG_LUSTRE_TRANSLATE_ERRNOS) += errno.o
|
||||
|
||||
obj-$(CONFIG_PTLRPC_GSS) += gss/
|
||||
|
@ -1,8 +0,0 @@
|
||||
obj-$(CONFIG_LUSTRE_FS) := ptlrpc_gss.o
|
||||
|
||||
ptlrpc_gss-y := sec_gss.o gss_bulk.o gss_cli_upcall.o gss_svc_upcall.o \
|
||||
gss_rawobj.o lproc_gss.o gss_generic_token.o \
|
||||
gss_mech_switch.o gss_krb5_mech.o
|
||||
|
||||
|
||||
ccflags-y := -I$(src)/../include
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Modifications for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Somewhat simplified version of the gss api.
|
||||
*
|
||||
* Dug Song <dugsong@monkey.org>
|
||||
* Andy Adamson <andros@umich.edu>
|
||||
* Bruce Fields <bfields@umich.edu>
|
||||
* Copyright (c) 2000 The Regents of the University of Michigan
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PTLRPC_GSS_GSS_API_H_
|
||||
#define __PTLRPC_GSS_GSS_API_H_
|
||||
|
||||
struct gss_api_mech;
|
||||
|
||||
/* The mechanism-independent gss-api context: */
|
||||
struct gss_ctx {
|
||||
struct gss_api_mech *mech_type;
|
||||
void *internal_ctx_id;
|
||||
};
|
||||
|
||||
#define GSS_C_NO_BUFFER ((rawobj_t) 0)
|
||||
#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0)
|
||||
#define GSS_C_NULL_OID ((rawobj_t) 0)
|
||||
|
||||
/*
|
||||
* gss-api prototypes; note that these are somewhat simplified versions of
|
||||
* the prototypes specified in RFC 2744.
|
||||
*/
|
||||
__u32 lgss_import_sec_context(
|
||||
rawobj_t *input_token,
|
||||
struct gss_api_mech *mech,
|
||||
struct gss_ctx **ctx);
|
||||
__u32 lgss_copy_reverse_context(
|
||||
struct gss_ctx *ctx,
|
||||
struct gss_ctx **ctx_new);
|
||||
__u32 lgss_inquire_context(
|
||||
struct gss_ctx *ctx,
|
||||
unsigned long *endtime);
|
||||
__u32 lgss_get_mic(
|
||||
struct gss_ctx *ctx,
|
||||
int msgcnt,
|
||||
rawobj_t *msgs,
|
||||
int iovcnt,
|
||||
lnet_kiov_t *iovs,
|
||||
rawobj_t *mic_token);
|
||||
__u32 lgss_verify_mic(
|
||||
struct gss_ctx *ctx,
|
||||
int msgcnt,
|
||||
rawobj_t *msgs,
|
||||
int iovcnt,
|
||||
lnet_kiov_t *iovs,
|
||||
rawobj_t *mic_token);
|
||||
__u32 lgss_wrap(
|
||||
struct gss_ctx *ctx,
|
||||
rawobj_t *gsshdr,
|
||||
rawobj_t *msg,
|
||||
int msg_buflen,
|
||||
rawobj_t *out_token);
|
||||
__u32 lgss_unwrap(
|
||||
struct gss_ctx *ctx,
|
||||
rawobj_t *gsshdr,
|
||||
rawobj_t *token,
|
||||
rawobj_t *out_msg);
|
||||
__u32 lgss_prep_bulk(
|
||||
struct gss_ctx *gctx,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
__u32 lgss_wrap_bulk(
|
||||
struct gss_ctx *gctx,
|
||||
struct ptlrpc_bulk_desc *desc,
|
||||
rawobj_t *token,
|
||||
int adj_nob);
|
||||
__u32 lgss_unwrap_bulk(
|
||||
struct gss_ctx *gctx,
|
||||
struct ptlrpc_bulk_desc *desc,
|
||||
rawobj_t *token,
|
||||
int adj_nob);
|
||||
__u32 lgss_delete_sec_context(
|
||||
struct gss_ctx **ctx);
|
||||
int lgss_display(
|
||||
struct gss_ctx *ctx,
|
||||
char *buf,
|
||||
int bufsize);
|
||||
|
||||
struct subflavor_desc {
|
||||
__u32 sf_subflavor;
|
||||
__u32 sf_qop;
|
||||
__u32 sf_service;
|
||||
char *sf_name;
|
||||
};
|
||||
|
||||
/* Each mechanism is described by the following struct: */
|
||||
struct gss_api_mech {
|
||||
struct list_head gm_list;
|
||||
struct module *gm_owner;
|
||||
char *gm_name;
|
||||
rawobj_t gm_oid;
|
||||
atomic_t gm_count;
|
||||
struct gss_api_ops *gm_ops;
|
||||
int gm_sf_num;
|
||||
struct subflavor_desc *gm_sfs;
|
||||
};
|
||||
|
||||
/* and must provide the following operations: */
|
||||
struct gss_api_ops {
|
||||
__u32 (*gss_import_sec_context)(
|
||||
rawobj_t *input_token,
|
||||
struct gss_ctx *ctx);
|
||||
__u32 (*gss_copy_reverse_context)(
|
||||
struct gss_ctx *ctx,
|
||||
struct gss_ctx *ctx_new);
|
||||
__u32 (*gss_inquire_context)(
|
||||
struct gss_ctx *ctx,
|
||||
unsigned long *endtime);
|
||||
__u32 (*gss_get_mic)(
|
||||
struct gss_ctx *ctx,
|
||||
int msgcnt,
|
||||
rawobj_t *msgs,
|
||||
int iovcnt,
|
||||
lnet_kiov_t *iovs,
|
||||
rawobj_t *mic_token);
|
||||
__u32 (*gss_verify_mic)(
|
||||
struct gss_ctx *ctx,
|
||||
int msgcnt,
|
||||
rawobj_t *msgs,
|
||||
int iovcnt,
|
||||
lnet_kiov_t *iovs,
|
||||
rawobj_t *mic_token);
|
||||
__u32 (*gss_wrap)(
|
||||
struct gss_ctx *ctx,
|
||||
rawobj_t *gsshdr,
|
||||
rawobj_t *msg,
|
||||
int msg_buflen,
|
||||
rawobj_t *out_token);
|
||||
__u32 (*gss_unwrap)(
|
||||
struct gss_ctx *ctx,
|
||||
rawobj_t *gsshdr,
|
||||
rawobj_t *token,
|
||||
rawobj_t *out_msg);
|
||||
__u32 (*gss_prep_bulk)(
|
||||
struct gss_ctx *gctx,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
__u32 (*gss_wrap_bulk)(
|
||||
struct gss_ctx *gctx,
|
||||
struct ptlrpc_bulk_desc *desc,
|
||||
rawobj_t *token,
|
||||
int adj_nob);
|
||||
__u32 (*gss_unwrap_bulk)(
|
||||
struct gss_ctx *gctx,
|
||||
struct ptlrpc_bulk_desc *desc,
|
||||
rawobj_t *token,
|
||||
int adj_nob);
|
||||
void (*gss_delete_sec_context)(
|
||||
void *ctx);
|
||||
int (*gss_display)(
|
||||
struct gss_ctx *ctx,
|
||||
char *buf,
|
||||
int bufsize);
|
||||
};
|
||||
|
||||
int lgss_mech_register(struct gss_api_mech *mech);
|
||||
void lgss_mech_unregister(struct gss_api_mech *mech);
|
||||
|
||||
struct gss_api_mech * lgss_OID_to_mech(rawobj_t *oid);
|
||||
struct gss_api_mech * lgss_name_to_mech(char *name);
|
||||
struct gss_api_mech * lgss_subflavor_to_mech(__u32 subflavor);
|
||||
|
||||
struct gss_api_mech * lgss_mech_get(struct gss_api_mech *mech);
|
||||
void lgss_mech_put(struct gss_api_mech *mech);
|
||||
|
||||
#endif /* __PTLRPC_GSS_GSS_API_H_ */
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Modifications for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* minimal asn1 for generic encoding/decoding of gss tokens
|
||||
*
|
||||
* Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
|
||||
* lib/gssapi/krb5/gssapiP_krb5.h, and others
|
||||
*
|
||||
* Copyright (c) 2000 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Andy Adamson <andros@umich.edu>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1995 by the Massachusetts Institute of Technology.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Export of this software from the United States of America may
|
||||
* require a specific license from the United States Government.
|
||||
* It is the responsibility of any person or organization contemplating
|
||||
* export to obtain such a license before exporting.
|
||||
*
|
||||
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
* distribute this software and its documentation for any purpose and
|
||||
* without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright notice and
|
||||
* this permission notice appear in supporting documentation, and that
|
||||
* the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
* to distribution of the software without specific, written prior
|
||||
* permission. Furthermore if you modify this software you must label
|
||||
* your software as modified software and not distribute it in such a
|
||||
* fashion that it might be confused with the original M.I.T. software.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* from gssapi_err_generic.h */
|
||||
#define G_BAD_SERVICE_NAME (-2045022976L)
|
||||
#define G_BAD_STRING_UID (-2045022975L)
|
||||
#define G_NOUSER (-2045022974L)
|
||||
#define G_VALIDATE_FAILED (-2045022973L)
|
||||
#define G_BUFFER_ALLOC (-2045022972L)
|
||||
#define G_BAD_MSG_CTX (-2045022971L)
|
||||
#define G_WRONG_SIZE (-2045022970L)
|
||||
#define G_BAD_USAGE (-2045022969L)
|
||||
#define G_UNKNOWN_QOP (-2045022968L)
|
||||
#define G_NO_HOSTNAME (-2045022967L)
|
||||
#define G_BAD_HOSTNAME (-2045022966L)
|
||||
#define G_WRONG_MECH (-2045022965L)
|
||||
#define G_BAD_TOK_HEADER (-2045022964L)
|
||||
#define G_BAD_DIRECTION (-2045022963L)
|
||||
#define G_TOK_TRUNC (-2045022962L)
|
||||
#define G_REFLECT (-2045022961L)
|
||||
#define G_WRONG_TOKID (-2045022960L)
|
||||
|
||||
#define g_OID_equal(o1, o2) \
|
||||
(((o1)->len == (o2)->len) && \
|
||||
(memcmp((o1)->data, (o2)->data, (int) (o1)->len) == 0))
|
||||
|
||||
__u32 g_verify_token_header(rawobj_t *mech,
|
||||
int *body_size,
|
||||
unsigned char **buf_in,
|
||||
int toksize);
|
||||
|
||||
__u32 g_get_mech_oid(rawobj_t *mech,
|
||||
rawobj_t *in_buf);
|
||||
|
||||
int g_token_size(rawobj_t *mech,
|
||||
unsigned int body_size);
|
||||
|
||||
void g_make_token_header(rawobj_t *mech,
|
||||
int body_size,
|
||||
unsigned char **buf);
|
@ -1,505 +0,0 @@
|
||||
/*
|
||||
* GPL HEADER START
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* 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_bulk.c
|
||||
*
|
||||
* Author: Eric Mei <eric.mei@sun.com>
|
||||
*/
|
||||
|
||||
#define DEBUG_SUBSYSTEM S_SEC
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/crypto.h>
|
||||
|
||||
#include <obd.h>
|
||||
#include <obd_class.h>
|
||||
#include <obd_support.h>
|
||||
#include <lustre/lustre_idl.h>
|
||||
#include <lustre_net.h>
|
||||
#include <lustre_import.h>
|
||||
#include <lustre_sec.h>
|
||||
|
||||
#include "gss_err.h"
|
||||
#include "gss_internal.h"
|
||||
#include "gss_api.h"
|
||||
|
||||
int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
|
||||
struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
struct gss_cli_ctx *gctx;
|
||||
struct lustre_msg *msg;
|
||||
struct ptlrpc_bulk_sec_desc *bsd;
|
||||
rawobj_t token;
|
||||
__u32 maj;
|
||||
int offset;
|
||||
int rc;
|
||||
|
||||
LASSERT(req->rq_pack_bulk);
|
||||
LASSERT(req->rq_bulk_read || req->rq_bulk_write);
|
||||
|
||||
gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
|
||||
LASSERT(gctx->gc_mechctx);
|
||||
|
||||
switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
|
||||
case SPTLRPC_SVC_NULL:
|
||||
LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
|
||||
msg = req->rq_reqbuf;
|
||||
offset = msg->lm_bufcount - 1;
|
||||
break;
|
||||
case SPTLRPC_SVC_AUTH:
|
||||
case SPTLRPC_SVC_INTG:
|
||||
LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
|
||||
msg = req->rq_reqbuf;
|
||||
offset = msg->lm_bufcount - 2;
|
||||
break;
|
||||
case SPTLRPC_SVC_PRIV:
|
||||
LASSERT(req->rq_clrbuf->lm_bufcount >= 2);
|
||||
msg = req->rq_clrbuf;
|
||||
offset = msg->lm_bufcount - 1;
|
||||
break;
|
||||
default:
|
||||
LBUG();
|
||||
}
|
||||
|
||||
bsd = lustre_msg_buf(msg, offset, sizeof(*bsd));
|
||||
bsd->bsd_version = 0;
|
||||
bsd->bsd_flags = 0;
|
||||
bsd->bsd_type = SPTLRPC_BULK_DEFAULT;
|
||||
bsd->bsd_svc = SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc);
|
||||
|
||||
if (bsd->bsd_svc == SPTLRPC_BULK_SVC_NULL)
|
||||
return 0;
|
||||
|
||||
LASSERT(bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
|
||||
bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV);
|
||||
|
||||
if (req->rq_bulk_read) {
|
||||
/*
|
||||
* bulk read: prepare receiving pages only for privacy mode.
|
||||
*/
|
||||
if (bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
|
||||
return gss_cli_prep_bulk(req, desc);
|
||||
} else {
|
||||
/*
|
||||
* bulk write: sign or encrypt bulk pages.
|
||||
*/
|
||||
bsd->bsd_nob = desc->bd_nob;
|
||||
|
||||
if (bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
|
||||
/* integrity mode */
|
||||
token.data = bsd->bsd_data;
|
||||
token.len = lustre_msg_buflen(msg, offset) -
|
||||
sizeof(*bsd);
|
||||
|
||||
maj = lgss_get_mic(gctx->gc_mechctx, 0, NULL,
|
||||
desc->bd_iov_count, desc->bd_iov,
|
||||
&token);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
CWARN("failed to sign bulk data: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
} else {
|
||||
/* privacy mode */
|
||||
if (desc->bd_iov_count == 0)
|
||||
return 0;
|
||||
|
||||
rc = sptlrpc_enc_pool_get_pages(desc);
|
||||
if (rc) {
|
||||
CERROR("bulk write: failed to allocate "
|
||||
"encryption pages: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
token.data = bsd->bsd_data;
|
||||
token.len = lustre_msg_buflen(msg, offset) -
|
||||
sizeof(*bsd);
|
||||
|
||||
maj = lgss_wrap_bulk(gctx->gc_mechctx, desc, &token, 0);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
CWARN("fail to encrypt bulk data: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
|
||||
struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
struct gss_cli_ctx *gctx;
|
||||
struct lustre_msg *rmsg, *vmsg;
|
||||
struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
|
||||
rawobj_t token;
|
||||
__u32 maj;
|
||||
int roff, voff;
|
||||
|
||||
LASSERT(req->rq_pack_bulk);
|
||||
LASSERT(req->rq_bulk_read || req->rq_bulk_write);
|
||||
|
||||
switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
|
||||
case SPTLRPC_SVC_NULL:
|
||||
vmsg = req->rq_repdata;
|
||||
LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 3);
|
||||
voff = vmsg->lm_bufcount - 1;
|
||||
|
||||
rmsg = req->rq_reqbuf;
|
||||
LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 3);
|
||||
roff = rmsg->lm_bufcount - 1; /* last segment */
|
||||
break;
|
||||
case SPTLRPC_SVC_AUTH:
|
||||
case SPTLRPC_SVC_INTG:
|
||||
vmsg = req->rq_repdata;
|
||||
LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 4);
|
||||
voff = vmsg->lm_bufcount - 2;
|
||||
|
||||
rmsg = req->rq_reqbuf;
|
||||
LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 4);
|
||||
roff = rmsg->lm_bufcount - 2; /* second last segment */
|
||||
break;
|
||||
case SPTLRPC_SVC_PRIV:
|
||||
vmsg = req->rq_repdata;
|
||||
LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 2);
|
||||
voff = vmsg->lm_bufcount - 1;
|
||||
|
||||
rmsg = req->rq_clrbuf;
|
||||
LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 2);
|
||||
roff = rmsg->lm_bufcount - 1; /* last segment */
|
||||
break;
|
||||
default:
|
||||
LBUG();
|
||||
}
|
||||
|
||||
bsdr = lustre_msg_buf(rmsg, roff, sizeof(*bsdr));
|
||||
bsdv = lustre_msg_buf(vmsg, voff, sizeof(*bsdv));
|
||||
LASSERT(bsdr && bsdv);
|
||||
|
||||
if (bsdr->bsd_version != bsdv->bsd_version ||
|
||||
bsdr->bsd_type != bsdv->bsd_type ||
|
||||
bsdr->bsd_svc != bsdv->bsd_svc) {
|
||||
CERROR("bulk security descriptor mismatch: "
|
||||
"(%u,%u,%u) != (%u,%u,%u)\n",
|
||||
bsdr->bsd_version, bsdr->bsd_type, bsdr->bsd_svc,
|
||||
bsdv->bsd_version, bsdv->bsd_type, bsdv->bsd_svc);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
LASSERT(bsdv->bsd_svc == SPTLRPC_BULK_SVC_NULL ||
|
||||
bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
|
||||
bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV);
|
||||
|
||||
/*
|
||||
* in privacy mode if return success, make sure bd_nob_transferred
|
||||
* is the actual size of the clear text, otherwise upper layer
|
||||
* may be surprised.
|
||||
*/
|
||||
if (req->rq_bulk_write) {
|
||||
if (bsdv->bsd_flags & BSD_FL_ERR) {
|
||||
CERROR("server reported bulk i/o failure\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
|
||||
desc->bd_nob_transferred = desc->bd_nob;
|
||||
} else {
|
||||
/*
|
||||
* bulk read, upon return success, bd_nob_transferred is
|
||||
* the size of plain text actually received.
|
||||
*/
|
||||
gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
|
||||
LASSERT(gctx->gc_mechctx);
|
||||
|
||||
if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
|
||||
int i, nob;
|
||||
|
||||
/* fix the actual data size */
|
||||
for (i = 0, nob = 0; i < desc->bd_iov_count; i++) {
|
||||
if (desc->bd_iov[i].kiov_len + nob >
|
||||
desc->bd_nob_transferred) {
|
||||
desc->bd_iov[i].kiov_len =
|
||||
desc->bd_nob_transferred - nob;
|
||||
}
|
||||
nob += desc->bd_iov[i].kiov_len;
|
||||
}
|
||||
|
||||
token.data = bsdv->bsd_data;
|
||||
token.len = lustre_msg_buflen(vmsg, voff) -
|
||||
sizeof(*bsdv);
|
||||
|
||||
maj = lgss_verify_mic(gctx->gc_mechctx, 0, NULL,
|
||||
desc->bd_iov_count, desc->bd_iov,
|
||||
&token);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
CERROR("failed to verify bulk read: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
} else if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV) {
|
||||
desc->bd_nob = bsdv->bsd_nob;
|
||||
if (desc->bd_nob == 0)
|
||||
return 0;
|
||||
|
||||
token.data = bsdv->bsd_data;
|
||||
token.len = lustre_msg_buflen(vmsg, voff) -
|
||||
sizeof(*bsdr);
|
||||
|
||||
maj = lgss_unwrap_bulk(gctx->gc_mechctx, desc,
|
||||
&token, 1);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
CERROR("failed to decrypt bulk read: %x\n",
|
||||
maj);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
desc->bd_nob_transferred = desc->bd_nob;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gss_prep_bulk(struct ptlrpc_bulk_desc *desc,
|
||||
struct gss_ctx *mechctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (desc->bd_iov_count == 0)
|
||||
return 0;
|
||||
|
||||
rc = sptlrpc_enc_pool_get_pages(desc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (lgss_prep_bulk(mechctx, desc) != GSS_S_COMPLETE)
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gss_cli_prep_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
int rc;
|
||||
|
||||
LASSERT(req->rq_cli_ctx);
|
||||
LASSERT(req->rq_pack_bulk);
|
||||
LASSERT(req->rq_bulk_read);
|
||||
|
||||
if (SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc) != SPTLRPC_BULK_SVC_PRIV)
|
||||
return 0;
|
||||
|
||||
rc = gss_prep_bulk(desc, ctx2gctx(req->rq_cli_ctx)->gc_mechctx);
|
||||
if (rc)
|
||||
CERROR("bulk read: failed to prepare encryption "
|
||||
"pages: %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gss_svc_prep_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
struct gss_svc_reqctx *grctx;
|
||||
struct ptlrpc_bulk_sec_desc *bsd;
|
||||
int rc;
|
||||
|
||||
LASSERT(req->rq_svc_ctx);
|
||||
LASSERT(req->rq_pack_bulk);
|
||||
LASSERT(req->rq_bulk_write);
|
||||
|
||||
grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
|
||||
LASSERT(grctx->src_reqbsd);
|
||||
LASSERT(grctx->src_repbsd);
|
||||
LASSERT(grctx->src_ctx);
|
||||
LASSERT(grctx->src_ctx->gsc_mechctx);
|
||||
|
||||
bsd = grctx->src_reqbsd;
|
||||
if (bsd->bsd_svc != SPTLRPC_BULK_SVC_PRIV)
|
||||
return 0;
|
||||
|
||||
rc = gss_prep_bulk(desc, grctx->src_ctx->gsc_mechctx);
|
||||
if (rc)
|
||||
CERROR("bulk write: failed to prepare encryption "
|
||||
"pages: %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
struct gss_svc_reqctx *grctx;
|
||||
struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
|
||||
rawobj_t token;
|
||||
__u32 maj;
|
||||
|
||||
LASSERT(req->rq_svc_ctx);
|
||||
LASSERT(req->rq_pack_bulk);
|
||||
LASSERT(req->rq_bulk_write);
|
||||
|
||||
grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
|
||||
|
||||
LASSERT(grctx->src_reqbsd);
|
||||
LASSERT(grctx->src_repbsd);
|
||||
LASSERT(grctx->src_ctx);
|
||||
LASSERT(grctx->src_ctx->gsc_mechctx);
|
||||
|
||||
bsdr = grctx->src_reqbsd;
|
||||
bsdv = grctx->src_repbsd;
|
||||
|
||||
/* bsdr has been sanity checked during unpacking */
|
||||
bsdv->bsd_version = 0;
|
||||
bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
|
||||
bsdv->bsd_svc = bsdr->bsd_svc;
|
||||
bsdv->bsd_flags = 0;
|
||||
|
||||
switch (bsdv->bsd_svc) {
|
||||
case SPTLRPC_BULK_SVC_INTG:
|
||||
token.data = bsdr->bsd_data;
|
||||
token.len = grctx->src_reqbsd_size - sizeof(*bsdr);
|
||||
|
||||
maj = lgss_verify_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
|
||||
desc->bd_iov_count, desc->bd_iov, &token);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
bsdv->bsd_flags |= BSD_FL_ERR;
|
||||
CERROR("failed to verify bulk signature: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
break;
|
||||
case SPTLRPC_BULK_SVC_PRIV:
|
||||
if (bsdr->bsd_nob != desc->bd_nob) {
|
||||
bsdv->bsd_flags |= BSD_FL_ERR;
|
||||
CERROR("prepared nob %d doesn't match the actual "
|
||||
"nob %d\n", desc->bd_nob, bsdr->bsd_nob);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (desc->bd_iov_count == 0) {
|
||||
LASSERT(desc->bd_nob == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
token.data = bsdr->bsd_data;
|
||||
token.len = grctx->src_reqbsd_size - sizeof(*bsdr);
|
||||
|
||||
maj = lgss_unwrap_bulk(grctx->src_ctx->gsc_mechctx,
|
||||
desc, &token, 0);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
bsdv->bsd_flags |= BSD_FL_ERR;
|
||||
CERROR("failed decrypt bulk data: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gss_svc_wrap_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
struct gss_svc_reqctx *grctx;
|
||||
struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
|
||||
rawobj_t token;
|
||||
__u32 maj;
|
||||
int rc;
|
||||
|
||||
LASSERT(req->rq_svc_ctx);
|
||||
LASSERT(req->rq_pack_bulk);
|
||||
LASSERT(req->rq_bulk_read);
|
||||
|
||||
grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
|
||||
|
||||
LASSERT(grctx->src_reqbsd);
|
||||
LASSERT(grctx->src_repbsd);
|
||||
LASSERT(grctx->src_ctx);
|
||||
LASSERT(grctx->src_ctx->gsc_mechctx);
|
||||
|
||||
bsdr = grctx->src_reqbsd;
|
||||
bsdv = grctx->src_repbsd;
|
||||
|
||||
/* bsdr has been sanity checked during unpacking */
|
||||
bsdv->bsd_version = 0;
|
||||
bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
|
||||
bsdv->bsd_svc = bsdr->bsd_svc;
|
||||
bsdv->bsd_flags = 0;
|
||||
|
||||
switch (bsdv->bsd_svc) {
|
||||
case SPTLRPC_BULK_SVC_INTG:
|
||||
token.data = bsdv->bsd_data;
|
||||
token.len = grctx->src_repbsd_size - sizeof(*bsdv);
|
||||
|
||||
maj = lgss_get_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
|
||||
desc->bd_iov_count, desc->bd_iov, &token);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
bsdv->bsd_flags |= BSD_FL_ERR;
|
||||
CERROR("failed to sign bulk data: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
break;
|
||||
case SPTLRPC_BULK_SVC_PRIV:
|
||||
bsdv->bsd_nob = desc->bd_nob;
|
||||
|
||||
if (desc->bd_iov_count == 0) {
|
||||
LASSERT(desc->bd_nob == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = sptlrpc_enc_pool_get_pages(desc);
|
||||
if (rc) {
|
||||
bsdv->bsd_flags |= BSD_FL_ERR;
|
||||
CERROR("bulk read: failed to allocate encryption "
|
||||
"pages: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
token.data = bsdv->bsd_data;
|
||||
token.len = grctx->src_repbsd_size - sizeof(*bsdv);
|
||||
|
||||
maj = lgss_wrap_bulk(grctx->src_ctx->gsc_mechctx,
|
||||
desc, &token, 1);
|
||||
if (maj != GSS_S_COMPLETE) {
|
||||
bsdv->bsd_flags |= BSD_FL_ERR;
|
||||
CERROR("failed to encrypt bulk data: %x\n", maj);
|
||||
return -EACCES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,446 +0,0 @@
|
||||
/*
|
||||
* GPL HEADER START
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 2011, 2012, Intel Corporation.
|
||||
*/
|
||||
/*
|
||||
* 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 <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
#define DEBUG_SUBSYSTEM S_SEC
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <obd.h>
|
||||
#include <obd_class.h>
|
||||
#include <obd_support.h>
|
||||
#include <lustre/lustre_idl.h>
|
||||
#include <lustre_net.h>
|
||||
#include <lustre_import.h>
|
||||
#include <lustre_sec.h>
|
||||
|
||||
#include "gss_err.h"
|
||||
#include "gss_internal.h"
|
||||
#include "gss_api.h"
|
||||
|
||||
/**********************************************
|
||||
* gss context init/fini helper *
|
||||
**********************************************/
|
||||
|
||||
static
|
||||
int ctx_init_pack_request(struct obd_import *imp,
|
||||
struct ptlrpc_request *req,
|
||||
int lustre_srv,
|
||||
uid_t uid, gid_t gid,
|
||||
long token_size,
|
||||
char __user *token)
|
||||
{
|
||||
struct lustre_msg *msg = req->rq_reqbuf;
|
||||
struct gss_sec *gsec;
|
||||
struct gss_header *ghdr;
|
||||
struct ptlrpc_user_desc *pud;
|
||||
__u32 *p, size, offset = 2;
|
||||
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;
|
||||
ghdr->gh_svc = SPTLRPC_SVC_NULL;
|
||||
ghdr->gh_handle.len = 0;
|
||||
|
||||
/* fix the user desc */
|
||||
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;
|
||||
pud->pud_gid = pud->pud_fsgid = gid;
|
||||
pud->pud_cap = 0;
|
||||
pud->pud_ngroups = 0;
|
||||
offset++;
|
||||
}
|
||||
|
||||
/* security payload */
|
||||
p = lustre_msg_buf(msg, offset, 0);
|
||||
size = msg->lm_buflens[offset];
|
||||
LASSERT(p);
|
||||
|
||||
/* 1. lustre svc type */
|
||||
LASSERT(size > 4);
|
||||
*p++ = cpu_to_le32(lustre_srv);
|
||||
size -= 4;
|
||||
|
||||
/* 2. target uuid */
|
||||
obj.len = strlen(imp->imp_obd->u.cli.cl_target_uuid.uuid) + 1;
|
||||
obj.data = imp->imp_obd->u.cli.cl_target_uuid.uuid;
|
||||
if (rawobj_serialize(&obj, &p, &size))
|
||||
LBUG();
|
||||
|
||||
/* 3. reverse context handle. actually only needed by root user,
|
||||
* 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))
|
||||
LBUG();
|
||||
|
||||
/* 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)) {
|
||||
CERROR("can't copy token\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int ctx_init_parse_reply(struct lustre_msg *msg, int swabbed,
|
||||
char __user *outbuf, long outlen)
|
||||
{
|
||||
struct gss_rep_header *ghdr;
|
||||
__u32 obj_len, round_len;
|
||||
__u32 status, effective = 0;
|
||||
|
||||
if (msg->lm_bufcount != 3) {
|
||||
CERROR("unexpected bufcount %u\n", msg->lm_bufcount);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
ghdr = (struct gss_rep_header *) gss_swab_header(msg, 0, swabbed);
|
||||
if (ghdr == NULL) {
|
||||
CERROR("unable to extract gss reply header\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (ghdr->gh_version != PTLRPC_GSS_VERSION) {
|
||||
CERROR("invalid gss version %u\n", ghdr->gh_version);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
effective = 0;
|
||||
|
||||
if (copy_to_user(outbuf, &status, 4))
|
||||
return -EFAULT;
|
||||
outbuf += 4;
|
||||
if (copy_to_user(outbuf, &ghdr->gh_major, 4))
|
||||
return -EFAULT;
|
||||
outbuf += 4;
|
||||
if (copy_to_user(outbuf, &ghdr->gh_minor, 4))
|
||||
return -EFAULT;
|
||||
outbuf += 4;
|
||||
if (copy_to_user(outbuf, &ghdr->gh_seqwin, 4))
|
||||
return -EFAULT;
|
||||
outbuf += 4;
|
||||
effective += 4 * 4;
|
||||
|
||||
/* handle */
|
||||
obj_len = ghdr->gh_handle.len;
|
||||
round_len = (obj_len + 3) & ~ 3;
|
||||
if (copy_to_user(outbuf, &obj_len, 4))
|
||||
return -EFAULT;
|
||||
outbuf += 4;
|
||||
if (copy_to_user(outbuf, (char *) ghdr->gh_handle.data, round_len))
|
||||
return -EFAULT;
|
||||
outbuf += round_len;
|
||||
effective += 4 + round_len;
|
||||
|
||||
/* out token */
|
||||
obj_len = msg->lm_buflens[2];
|
||||
round_len = (obj_len + 3) & ~ 3;
|
||||
if (copy_to_user(outbuf, &obj_len, 4))
|
||||
return -EFAULT;
|
||||
outbuf += 4;
|
||||
if (copy_to_user(outbuf, lustre_msg_buf(msg, 2, 0), round_len))
|
||||
return -EFAULT;
|
||||
outbuf += round_len;
|
||||
effective += 4 + round_len;
|
||||
|
||||
return effective;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
};
|
||||
|
||||
int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
|
||||
{
|
||||
struct obd_import *imp;
|
||||
struct ptlrpc_request *req;
|
||||
struct lgssd_ioctl_param param;
|
||||
struct obd_device *obd;
|
||||
char obdname[64];
|
||||
long lsize;
|
||||
int rc;
|
||||
|
||||
if (count != 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))) {
|
||||
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, param.uuid, sizeof(obdname)) <= 0) {
|
||||
CERROR("Invalid obdname pointer\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
obd = class_name2obd(obdname);
|
||||
if (!obd) {
|
||||
CERROR("no such obd %s\n", obdname);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(!obd->obd_set_up)) {
|
||||
CERROR("obd %s not setup\n", obdname);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock(&obd->obd_dev_lock);
|
||||
if (obd->obd_stopping) {
|
||||
CERROR("obd %s has stopped\n", obdname);
|
||||
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);
|
||||
spin_unlock(&obd->obd_dev_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
spin_unlock(&obd->obd_dev_lock);
|
||||
|
||||
down_read(&obd->u.cli.cl_sem);
|
||||
if (obd->u.cli.cl_import == NULL) {
|
||||
CERROR("obd %s: import has gone\n", obd->obd_name);
|
||||
up_read(&obd->u.cli.cl_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
imp = class_import_get(obd->u.cli.cl_import);
|
||||
up_read(&obd->u.cli.cl_sem);
|
||||
|
||||
if (imp->imp_deactive) {
|
||||
CERROR("import has been deactivated\n");
|
||||
class_import_put(imp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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,
|
||||
param.uid, param.gid,
|
||||
param.send_token_size,
|
||||
param.send_token);
|
||||
if (rc) {
|
||||
param.status = rc;
|
||||
goto out_copy;
|
||||
}
|
||||
|
||||
ptlrpc_request_set_replen(req);
|
||||
|
||||
rc = ptlrpc_queue_wait(req);
|
||||
if (rc) {
|
||||
/* If any _real_ denial be made, we expect server return
|
||||
* -EACCES reply or return success but indicate gss error
|
||||
* inside reply message. 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 = rc;
|
||||
if (rc != -EACCES)
|
||||
param.status = -ETIMEDOUT;
|
||||
goto out_copy;
|
||||
}
|
||||
|
||||
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;
|
||||
goto out_copy;
|
||||
}
|
||||
|
||||
param.status = 0;
|
||||
param.reply_length = lsize;
|
||||
|
||||
out_copy:
|
||||
if (copy_to_user(buffer, ¶m, sizeof(param)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
class_import_put(imp);
|
||||
ptlrpc_req_finished(req);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
|
||||
{
|
||||
struct ptlrpc_cli_ctx *ctx = &gctx->gc_base;
|
||||
struct obd_import *imp = ctx->cc_sec->ps_import;
|
||||
struct ptlrpc_request *req;
|
||||
struct ptlrpc_user_desc *pud;
|
||||
int rc;
|
||||
|
||||
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,
|
||||
ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
|
||||
return 0;
|
||||
}
|
||||
|
||||
might_sleep();
|
||||
|
||||
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_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 (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));
|
||||
LASSERT(pud);
|
||||
pud->pud_uid = pud->pud_fsuid = ctx->cc_vcred.vc_uid;
|
||||
pud->pud_gid = pud->pud_fsgid = ctx->cc_vcred.vc_gid;
|
||||
pud->pud_cap = 0;
|
||||
pud->pud_ngroups = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
out_ref:
|
||||
ptlrpc_req_finished(req);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int __init gss_init_cli_upcall(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __exit gss_exit_cli_upcall(void)
|
||||
{
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Modifications for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Adapted from MIT Kerberos 5-1.2.1 include/gssapi/gssapi.h
|
||||
*
|
||||
* Copyright (c) 2002 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Andy Adamson <andros@umich.edu>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1993 by OpenVision Technologies, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appears in all copies and
|
||||
* that both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of OpenVision not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. OpenVision makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __PTLRPC_GSS_GSS_ERR_H_
|
||||
#define __PTLRPC_GSS_GSS_ERR_H_
|
||||
|
||||
typedef unsigned int OM_uint32;
|
||||
|
||||
/*
|
||||
* Flag bits for context-level services.
|
||||
*/
|
||||
#define GSS_C_DELEG_FLAG (1)
|
||||
#define GSS_C_MUTUAL_FLAG (2)
|
||||
#define GSS_C_REPLAY_FLAG (4)
|
||||
#define GSS_C_SEQUENCE_FLAG (8)
|
||||
#define GSS_C_CONF_FLAG (16)
|
||||
#define GSS_C_INTEG_FLAG (32)
|
||||
#define GSS_C_ANON_FLAG (64)
|
||||
#define GSS_C_PROT_READY_FLAG (128)
|
||||
#define GSS_C_TRANS_FLAG (256)
|
||||
|
||||
/*
|
||||
* Credential usage options
|
||||
*/
|
||||
#define GSS_C_BOTH (0)
|
||||
#define GSS_C_INITIATE (1)
|
||||
#define GSS_C_ACCEPT (2)
|
||||
|
||||
/*
|
||||
* Status code types for gss_display_status
|
||||
*/
|
||||
#define GSS_C_GSS_CODE (1)
|
||||
#define GSS_C_MECH_CODE (2)
|
||||
|
||||
|
||||
/*
|
||||
* Define the default Quality of Protection for per-message services. Note
|
||||
* that an implementation that offers multiple levels of QOP may either reserve
|
||||
* a value (for example zero, as assumed here) to mean "default protection", or
|
||||
* alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
|
||||
* QOP value. However a value of 0 should always be interpreted by a GSSAPI
|
||||
* implementation as a request for the default protection level.
|
||||
*/
|
||||
#define GSS_C_QOP_DEFAULT (0)
|
||||
|
||||
/*
|
||||
* Expiration time of 2^32-1 seconds means infinite lifetime for a
|
||||
* credential or security context
|
||||
*/
|
||||
#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
|
||||
|
||||
|
||||
/* Major status codes */
|
||||
|
||||
#define GSS_S_COMPLETE (0)
|
||||
|
||||
/*
|
||||
* Some "helper" definitions to make the status code macros obvious.
|
||||
*/
|
||||
#define GSS_C_CALLING_ERROR_OFFSET (24)
|
||||
#define GSS_C_ROUTINE_ERROR_OFFSET (16)
|
||||
#define GSS_C_SUPPLEMENTARY_OFFSET (0)
|
||||
#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
|
||||
#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
|
||||
#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
|
||||
|
||||
/*
|
||||
* The macros that test status codes for error conditions. Note that the
|
||||
* GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
|
||||
* evaluates its argument only once.
|
||||
*/
|
||||
#define GSS_CALLING_ERROR(x) \
|
||||
((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
|
||||
#define GSS_ROUTINE_ERROR(x) \
|
||||
((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
|
||||
#define GSS_SUPPLEMENTARY_INFO(x) \
|
||||
((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
|
||||
#define GSS_ERROR(x) \
|
||||
((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
|
||||
(GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
|
||||
|
||||
/*
|
||||
* Now the actual status code definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Calling errors:
|
||||
*/
|
||||
#define GSS_S_CALL_INACCESSIBLE_READ \
|
||||
(((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
|
||||
#define GSS_S_CALL_INACCESSIBLE_WRITE \
|
||||
(((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
|
||||
#define GSS_S_CALL_BAD_STRUCTURE \
|
||||
(((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
|
||||
|
||||
/*
|
||||
* Routine errors:
|
||||
*/
|
||||
#define GSS_S_BAD_MECH \
|
||||
(((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_BAD_NAME \
|
||||
(((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_BAD_NAMETYPE \
|
||||
(((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_BAD_BINDINGS \
|
||||
(((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_BAD_STATUS \
|
||||
(((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_BAD_SIG \
|
||||
(((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_NO_CRED \
|
||||
(((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_NO_CONTEXT \
|
||||
(((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_DEFECTIVE_TOKEN \
|
||||
(((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_DEFECTIVE_CREDENTIAL \
|
||||
(((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_CREDENTIALS_EXPIRED \
|
||||
(((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_CONTEXT_EXPIRED \
|
||||
(((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_FAILURE \
|
||||
(((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_BAD_QOP \
|
||||
(((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_UNAUTHORIZED \
|
||||
(((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_UNAVAILABLE \
|
||||
(((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_DUPLICATE_ELEMENT \
|
||||
(((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
#define GSS_S_NAME_NOT_MN \
|
||||
(((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
|
||||
|
||||
/*
|
||||
* Supplementary info bits:
|
||||
*/
|
||||
#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
|
||||
#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
|
||||
#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
|
||||
#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
|
||||
#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
|
||||
|
||||
/* XXXX these are not part of the GSSAPI C bindings! (but should be) */
|
||||
|
||||
#define GSS_CALLING_ERROR_FIELD(x) \
|
||||
(((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
|
||||
#define GSS_ROUTINE_ERROR_FIELD(x) \
|
||||
(((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
|
||||
#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
|
||||
(((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
|
||||
|
||||
/* XXXX This is a necessary evil until the spec is fixed */
|
||||
#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
|
||||
|
||||
#endif /* __PTLRPC_GSS_GSS_ERR_H_ */
|
@ -1,296 +0,0 @@
|
||||
/*
|
||||
* Modifications for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2011, Intel Corporation.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* linux/net/sunrpc/gss_generic_token.c
|
||||
*
|
||||
* Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic/util_token.c
|
||||
*
|
||||
* Copyright (c) 2000 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Andy Adamson <andros@umich.edu>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1993 by OpenVision Technologies, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appears in all copies and
|
||||
* that both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of OpenVision not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. OpenVision makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define DEBUG_SUBSYSTEM S_SEC
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <obd.h>
|
||||
#include <obd_class.h>
|
||||
#include <obd_support.h>
|
||||
#include <lustre/lustre_idl.h>
|
||||
#include <lustre_net.h>
|
||||
#include <lustre_import.h>
|
||||
#include <lustre_sec.h>
|
||||
|
||||
#include "gss_err.h"
|
||||
#include "gss_internal.h"
|
||||
#include "gss_api.h"
|
||||
#include "gss_krb5.h"
|
||||
#include "gss_asn1.h"
|
||||
|
||||
|
||||
/* TWRITE_STR from gssapiP_generic.h */
|
||||
#define TWRITE_STR(ptr, str, len) \
|
||||
memcpy((ptr), (char *) (str), (len)); \
|
||||
(ptr) += (len);
|
||||
|
||||
/* XXXX this code currently makes the assumption that a mech oid will
|
||||
never be longer than 127 bytes. This assumption is not inherent in
|
||||
the interfaces, so the code can be fixed if the OSI namespace
|
||||
balloons unexpectedly. */
|
||||
|
||||
/* Each token looks like this:
|
||||
|
||||
0x60 tag for APPLICATION 0, SEQUENCE
|
||||
(constructed, definite-length)
|
||||
<length> possible multiple bytes, need to parse/generate
|
||||
0x06 tag for OBJECT IDENTIFIER
|
||||
<moid_length> compile-time constant string (assume 1 byte)
|
||||
<moid_bytes> compile-time constant string
|
||||
<inner_bytes> the ANY containing the application token
|
||||
bytes 0,1 are the token type
|
||||
bytes 2,n are the token data
|
||||
|
||||
For the purposes of this abstraction, the token "header" consists of
|
||||
the sequence tag and length octets, the mech OID DER encoding, and the
|
||||
first two inner bytes, which indicate the token type. The token
|
||||
"body" consists of everything else.
|
||||
|
||||
*/
|
||||
|
||||
static
|
||||
int der_length_size(int length)
|
||||
{
|
||||
if (length < (1 << 7))
|
||||
return 1;
|
||||
else if (length < (1 << 8))
|
||||
return 2;
|
||||
#if (SIZEOF_INT == 2)
|
||||
else
|
||||
return 3;
|
||||
#else
|
||||
else if (length < (1 << 16))
|
||||
return 3;
|
||||
else if (length < (1 << 24))
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
void der_write_length(unsigned char **buf, int length)
|
||||
{
|
||||
if (length < (1 << 7)) {
|
||||
*(*buf)++ = (unsigned char) length;
|
||||
} else {
|
||||
*(*buf)++ = (unsigned char) (der_length_size(length) + 127);
|
||||
#if (SIZEOF_INT > 2)
|
||||
if (length >= (1 << 24))
|
||||
*(*buf)++ = (unsigned char) (length >> 24);
|
||||
if (length >= (1 << 16))
|
||||
*(*buf)++ = (unsigned char) ((length >> 16) & 0xff);
|
||||
#endif
|
||||
if (length >= (1 << 8))
|
||||
*(*buf)++ = (unsigned char) ((length >> 8) & 0xff);
|
||||
*(*buf)++ = (unsigned char) (length & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* returns decoded length, or < 0 on failure. Advances buf and
|
||||
* decrements bufsize
|
||||
*/
|
||||
static
|
||||
int der_read_length(unsigned char **buf, int *bufsize)
|
||||
{
|
||||
unsigned char sf;
|
||||
int ret;
|
||||
|
||||
if (*bufsize < 1)
|
||||
return -1;
|
||||
sf = *(*buf)++;
|
||||
(*bufsize)--;
|
||||
if (sf & 0x80) {
|
||||
sf &= 0x7f;
|
||||
if (((*bufsize) - 1) < sf)
|
||||
return -1;
|
||||
if (sf > SIZEOF_INT)
|
||||
return -1;
|
||||
ret = 0;
|
||||
for (; sf; sf--) {
|
||||
ret = (ret << 8) + (*(*buf)++);
|
||||
(*bufsize)--;
|
||||
}
|
||||
} else {
|
||||
ret = sf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the length of a token, given the mech oid and the body size
|
||||
*/
|
||||
int g_token_size(rawobj_t *mech, unsigned int body_size)
|
||||
{
|
||||
/* set body_size to sequence contents size */
|
||||
body_size += 4 + (int) mech->len; /* NEED overflow check */
|
||||
return (1 + der_length_size(body_size) + body_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* fills in a buffer with the token header. The buffer is assumed to
|
||||
* be the right size. buf is advanced past the token header
|
||||
*/
|
||||
void g_make_token_header(rawobj_t *mech, int body_size, unsigned char **buf)
|
||||
{
|
||||
*(*buf)++ = 0x60;
|
||||
der_write_length(buf, 4 + mech->len + body_size);
|
||||
*(*buf)++ = 0x06;
|
||||
*(*buf)++ = (unsigned char) mech->len;
|
||||
TWRITE_STR(*buf, mech->data, ((int) mech->len));
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a buffer containing a token, reads and verifies the token,
|
||||
* leaving buf advanced past the token header, and setting body_size
|
||||
* to the number of remaining bytes. Returns 0 on success,
|
||||
* G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the
|
||||
* mechanism in the token does not match the mech argument. buf and
|
||||
* *body_size are left unmodified on error.
|
||||
*/
|
||||
__u32 g_verify_token_header(rawobj_t *mech, int *body_size,
|
||||
unsigned char **buf_in, int toksize)
|
||||
{
|
||||
unsigned char *buf = *buf_in;
|
||||
int seqsize;
|
||||
rawobj_t toid;
|
||||
int ret = 0;
|
||||
|
||||
toksize -= 1;
|
||||
if (0 > toksize)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
if (*buf++ != 0x60)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
seqsize = der_read_length(&buf, &toksize);
|
||||
if (seqsize < 0)
|
||||
return(G_BAD_TOK_HEADER);
|
||||
|
||||
if (seqsize != toksize)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
toksize -= 1;
|
||||
if (0 > toksize)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
if (*buf++ != 0x06)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
toksize -= 1;
|
||||
if (0 > toksize)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
toid.len = *buf++;
|
||||
|
||||
toksize -= toid.len;
|
||||
if (0 > toksize)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
toid.data = buf;
|
||||
buf += toid.len;
|
||||
|
||||
if (!g_OID_equal(&toid, mech))
|
||||
ret = G_WRONG_MECH;
|
||||
|
||||
/* G_WRONG_MECH is not returned immediately because it's more
|
||||
* important to return G_BAD_TOK_HEADER if the token header is
|
||||
* in fact bad
|
||||
*/
|
||||
toksize -= 2;
|
||||
if (0 > toksize)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
if (!ret) {
|
||||
*buf_in = buf;
|
||||
*body_size = toksize;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a buffer containing a token, returns a copy of the mech oid in
|
||||
* the parameter mech.
|
||||
*/
|
||||
__u32 g_get_mech_oid(rawobj_t *mech, rawobj_t *in_buf)
|
||||
{
|
||||
unsigned char *buf = in_buf->data;
|
||||
int len = in_buf->len;
|
||||
int ret = 0;
|
||||
int seqsize;
|
||||
|
||||
len -= 1;
|
||||
if (0 > len)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
if (*buf++ != 0x60)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
seqsize = der_read_length(&buf, &len);
|
||||
if (seqsize < 0)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
len -= 1;
|
||||
if (0 > len)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
if (*buf++ != 0x06)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
|
||||
len -= 1;
|
||||
if (0 > len)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
mech->len = *buf++;
|
||||
|
||||
len -= mech->len;
|
||||
if (0 > len)
|
||||
return (G_BAD_TOK_HEADER);
|
||||
OBD_ALLOC_LARGE(mech->data, mech->len);
|
||||
if (!mech->data)
|
||||
return (G_BUFFER_ALLOC);
|
||||
memcpy(mech->data, buf, mech->len);
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,526 +0,0 @@
|
||||
/*
|
||||
* Modified from NFSv4 project for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2012, Intel Corporation.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
#ifndef __PTLRPC_GSS_GSS_INTERNAL_H_
|
||||
#define __PTLRPC_GSS_GSS_INTERNAL_H_
|
||||
|
||||
#include <lustre_sec.h>
|
||||
|
||||
/*
|
||||
* rawobj stuff
|
||||
*/
|
||||
typedef struct netobj_s {
|
||||
__u32 len;
|
||||
__u8 data[0];
|
||||
} netobj_t;
|
||||
|
||||
#define NETOBJ_EMPTY ((netobj_t) { 0 })
|
||||
|
||||
typedef struct rawobj_s {
|
||||
__u32 len;
|
||||
__u8 *data;
|
||||
} rawobj_t;
|
||||
|
||||
#define RAWOBJ_EMPTY ((rawobj_t) { 0, NULL })
|
||||
|
||||
typedef struct rawobj_buf_s {
|
||||
__u32 dataoff;
|
||||
__u32 datalen;
|
||||
__u32 buflen;
|
||||
__u8 *buf;
|
||||
} rawobj_buf_t;
|
||||
|
||||
int rawobj_empty(rawobj_t *obj);
|
||||
int rawobj_alloc(rawobj_t *obj, char *buf, int len);
|
||||
void rawobj_free(rawobj_t *obj);
|
||||
int rawobj_equal(rawobj_t *a, rawobj_t *b);
|
||||
int rawobj_dup(rawobj_t *dest, rawobj_t *src);
|
||||
int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen);
|
||||
int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen);
|
||||
int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen);
|
||||
int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen);
|
||||
int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen);
|
||||
int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj);
|
||||
int rawobj_from_netobj_alloc(rawobj_t *obj, netobj_t *netobj);
|
||||
|
||||
int buffer_extract_bytes(const void **buf, __u32 *buflen,
|
||||
void *res, __u32 reslen);
|
||||
|
||||
/*
|
||||
* several timeout values. client refresh upcall timeout we using
|
||||
* default in pipefs implemnetation.
|
||||
*/
|
||||
#define __TIMEOUT_DELTA (10)
|
||||
|
||||
#define GSS_SECINIT_RPC_TIMEOUT \
|
||||
(obd_timeout < __TIMEOUT_DELTA ? \
|
||||
__TIMEOUT_DELTA : obd_timeout - __TIMEOUT_DELTA)
|
||||
|
||||
#define GSS_SECFINI_RPC_TIMEOUT (__TIMEOUT_DELTA)
|
||||
#define GSS_SECSVC_UPCALL_TIMEOUT (GSS_SECINIT_RPC_TIMEOUT)
|
||||
|
||||
/*
|
||||
* default gc interval
|
||||
*/
|
||||
#define GSS_GC_INTERVAL (60 * 60) /* 60 minutes */
|
||||
|
||||
static inline
|
||||
unsigned long gss_round_ctx_expiry(unsigned long expiry,
|
||||
unsigned long sec_flags)
|
||||
{
|
||||
if (sec_flags & PTLRPC_SEC_FL_REVERSE)
|
||||
return expiry;
|
||||
|
||||
if (get_seconds() + __TIMEOUT_DELTA <= expiry)
|
||||
return expiry - __TIMEOUT_DELTA;
|
||||
|
||||
return expiry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Max encryption element in block cipher algorithms.
|
||||
*/
|
||||
#define GSS_MAX_CIPHER_BLOCK (16)
|
||||
|
||||
/*
|
||||
* XXX make it visible of kernel and lgssd/lsvcgssd
|
||||
*/
|
||||
#define GSSD_INTERFACE_VERSION (1)
|
||||
|
||||
#define PTLRPC_GSS_VERSION (1)
|
||||
|
||||
|
||||
enum ptlrpc_gss_proc {
|
||||
PTLRPC_GSS_PROC_DATA = 0,
|
||||
PTLRPC_GSS_PROC_INIT = 1,
|
||||
PTLRPC_GSS_PROC_CONTINUE_INIT = 2,
|
||||
PTLRPC_GSS_PROC_DESTROY = 3,
|
||||
PTLRPC_GSS_PROC_ERR = 4,
|
||||
};
|
||||
|
||||
enum ptlrpc_gss_tgt {
|
||||
LUSTRE_GSS_TGT_MGS = 0,
|
||||
LUSTRE_GSS_TGT_MDS = 1,
|
||||
LUSTRE_GSS_TGT_OSS = 2,
|
||||
};
|
||||
|
||||
enum ptlrpc_gss_header_flags {
|
||||
LUSTRE_GSS_PACK_BULK = 1,
|
||||
LUSTRE_GSS_PACK_USER = 2,
|
||||
};
|
||||
|
||||
static inline
|
||||
__u32 import_to_gss_svc(struct obd_import *imp)
|
||||
{
|
||||
const char *name = imp->imp_obd->obd_type->typ_name;
|
||||
|
||||
if (!strcmp(name, LUSTRE_MGC_NAME))
|
||||
return LUSTRE_GSS_TGT_MGS;
|
||||
if (!strcmp(name, LUSTRE_MDC_NAME))
|
||||
return LUSTRE_GSS_TGT_MDS;
|
||||
if (!strcmp(name, LUSTRE_OSC_NAME))
|
||||
return LUSTRE_GSS_TGT_OSS;
|
||||
LBUG();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* following 3 header must have the same size and offset
|
||||
*/
|
||||
struct gss_header {
|
||||
__u8 gh_version; /* gss version */
|
||||
__u8 gh_sp; /* sec part */
|
||||
__u16 gh_pad0;
|
||||
__u32 gh_flags; /* wrap flags */
|
||||
__u32 gh_proc; /* proc */
|
||||
__u32 gh_seq; /* sequence */
|
||||
__u32 gh_svc; /* service */
|
||||
__u32 gh_pad1;
|
||||
__u32 gh_pad2;
|
||||
__u32 gh_pad3;
|
||||
netobj_t gh_handle; /* context handle */
|
||||
};
|
||||
|
||||
struct gss_rep_header {
|
||||
__u8 gh_version;
|
||||
__u8 gh_sp;
|
||||
__u16 gh_pad0;
|
||||
__u32 gh_flags;
|
||||
__u32 gh_proc;
|
||||
__u32 gh_major;
|
||||
__u32 gh_minor;
|
||||
__u32 gh_seqwin;
|
||||
__u32 gh_pad2;
|
||||
__u32 gh_pad3;
|
||||
netobj_t gh_handle;
|
||||
};
|
||||
|
||||
struct gss_err_header {
|
||||
__u8 gh_version;
|
||||
__u8 gh_sp;
|
||||
__u16 gh_pad0;
|
||||
__u32 gh_flags;
|
||||
__u32 gh_proc;
|
||||
__u32 gh_major;
|
||||
__u32 gh_minor;
|
||||
__u32 gh_pad1;
|
||||
__u32 gh_pad2;
|
||||
__u32 gh_pad3;
|
||||
netobj_t gh_handle;
|
||||
};
|
||||
|
||||
/*
|
||||
* part of wire context information send from client which be saved and
|
||||
* used later by server.
|
||||
*/
|
||||
struct gss_wire_ctx {
|
||||
__u32 gw_flags;
|
||||
__u32 gw_proc;
|
||||
__u32 gw_seq;
|
||||
__u32 gw_svc;
|
||||
rawobj_t gw_handle;
|
||||
};
|
||||
|
||||
#define PTLRPC_GSS_MAX_HANDLE_SIZE (8)
|
||||
#define PTLRPC_GSS_HEADER_SIZE (sizeof(struct gss_header) + \
|
||||
PTLRPC_GSS_MAX_HANDLE_SIZE)
|
||||
|
||||
|
||||
static inline __u64 gss_handle_to_u64(rawobj_t *handle)
|
||||
{
|
||||
if (handle->len != PTLRPC_GSS_MAX_HANDLE_SIZE)
|
||||
return -1;
|
||||
return *((__u64 *) handle->data);
|
||||
}
|
||||
|
||||
#define GSS_SEQ_WIN (2048)
|
||||
#define GSS_SEQ_WIN_MAIN GSS_SEQ_WIN
|
||||
#define GSS_SEQ_WIN_BACK (128)
|
||||
#define GSS_SEQ_REPACK_THRESHOLD (GSS_SEQ_WIN_MAIN / 2 + \
|
||||
GSS_SEQ_WIN_MAIN / 4)
|
||||
|
||||
struct gss_svc_seq_data {
|
||||
spinlock_t ssd_lock;
|
||||
/*
|
||||
* highest sequence number seen so far, for main and back window
|
||||
*/
|
||||
__u32 ssd_max_main;
|
||||
__u32 ssd_max_back;
|
||||
/*
|
||||
* main and back window
|
||||
* for i such that ssd_max - GSS_SEQ_WIN < i <= ssd_max, the i-th bit
|
||||
* of ssd_win is nonzero iff sequence number i has been seen already.
|
||||
*/
|
||||
unsigned long ssd_win_main[GSS_SEQ_WIN_MAIN/BITS_PER_LONG];
|
||||
unsigned long ssd_win_back[GSS_SEQ_WIN_BACK/BITS_PER_LONG];
|
||||
};
|
||||
|
||||
struct gss_svc_ctx {
|
||||
struct gss_ctx *gsc_mechctx;
|
||||
struct gss_svc_seq_data gsc_seqdata;
|
||||
rawobj_t gsc_rvs_hdl;
|
||||
__u32 gsc_rvs_seq;
|
||||
uid_t gsc_uid;
|
||||
gid_t gsc_gid;
|
||||
uid_t gsc_mapped_uid;
|
||||
unsigned int gsc_usr_root:1,
|
||||
gsc_usr_mds:1,
|
||||
gsc_usr_oss:1,
|
||||
gsc_remote:1,
|
||||
gsc_reverse:1;
|
||||
};
|
||||
|
||||
struct gss_svc_reqctx {
|
||||
struct ptlrpc_svc_ctx src_base;
|
||||
/*
|
||||
* context
|
||||
*/
|
||||
struct gss_wire_ctx src_wirectx;
|
||||
struct gss_svc_ctx *src_ctx;
|
||||
/*
|
||||
* record place of bulk_sec_desc in request/reply buffer
|
||||
*/
|
||||
struct ptlrpc_bulk_sec_desc *src_reqbsd;
|
||||
int src_reqbsd_size;
|
||||
struct ptlrpc_bulk_sec_desc *src_repbsd;
|
||||
int src_repbsd_size;
|
||||
/*
|
||||
* flags
|
||||
*/
|
||||
unsigned int src_init:1,
|
||||
src_init_continue:1,
|
||||
src_err_notify:1;
|
||||
int src_reserve_len;
|
||||
};
|
||||
|
||||
struct gss_cli_ctx {
|
||||
struct ptlrpc_cli_ctx gc_base;
|
||||
__u32 gc_flavor;
|
||||
__u32 gc_proc;
|
||||
__u32 gc_win;
|
||||
atomic_t gc_seq;
|
||||
rawobj_t gc_handle;
|
||||
struct gss_ctx *gc_mechctx;
|
||||
/* handle for the buddy svc ctx */
|
||||
rawobj_t gc_svc_handle;
|
||||
};
|
||||
|
||||
struct gss_cli_ctx_keyring {
|
||||
struct gss_cli_ctx gck_base;
|
||||
struct key *gck_key;
|
||||
struct timer_list *gck_timer;
|
||||
};
|
||||
|
||||
struct gss_sec {
|
||||
struct ptlrpc_sec gs_base;
|
||||
struct gss_api_mech *gs_mech;
|
||||
spinlock_t gs_lock;
|
||||
__u64 gs_rvs_hdl;
|
||||
};
|
||||
|
||||
struct gss_sec_pipefs {
|
||||
struct gss_sec gsp_base;
|
||||
int gsp_chash_size; /* must be 2^n */
|
||||
struct hlist_head gsp_chash[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME cleanup the keyring upcall mutexes
|
||||
*/
|
||||
#define HAVE_KEYRING_UPCALL_SERIALIZED 1
|
||||
|
||||
struct gss_sec_keyring {
|
||||
struct gss_sec gsk_base;
|
||||
/*
|
||||
* all contexts listed here. access is protected by sec spinlock.
|
||||
*/
|
||||
struct hlist_head gsk_clist;
|
||||
/*
|
||||
* specially point to root ctx (only one at a time). access is
|
||||
* protected by sec spinlock.
|
||||
*/
|
||||
struct ptlrpc_cli_ctx *gsk_root_ctx;
|
||||
/*
|
||||
* specially serialize upcalls for root context.
|
||||
*/
|
||||
struct mutex gsk_root_uc_lock;
|
||||
|
||||
#ifdef HAVE_KEYRING_UPCALL_SERIALIZED
|
||||
struct mutex gsk_uc_lock; /* serialize upcalls */
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline struct gss_cli_ctx *ctx2gctx(struct ptlrpc_cli_ctx *ctx)
|
||||
{
|
||||
return container_of(ctx, struct gss_cli_ctx, gc_base);
|
||||
}
|
||||
|
||||
static inline
|
||||
struct gss_cli_ctx_keyring *ctx2gctx_keyring(struct ptlrpc_cli_ctx *ctx)
|
||||
{
|
||||
return container_of(ctx2gctx(ctx),
|
||||
struct gss_cli_ctx_keyring, gck_base);
|
||||
}
|
||||
|
||||
static inline struct gss_sec *sec2gsec(struct ptlrpc_sec *sec)
|
||||
{
|
||||
return container_of(sec, struct gss_sec, gs_base);
|
||||
}
|
||||
|
||||
static inline struct gss_sec_pipefs *sec2gsec_pipefs(struct ptlrpc_sec *sec)
|
||||
{
|
||||
return container_of(sec2gsec(sec), struct gss_sec_pipefs, gsp_base);
|
||||
}
|
||||
|
||||
static inline struct gss_sec_keyring *sec2gsec_keyring(struct ptlrpc_sec *sec)
|
||||
{
|
||||
return container_of(sec2gsec(sec), struct gss_sec_keyring, gsk_base);
|
||||
}
|
||||
|
||||
|
||||
#define GSS_CTX_INIT_MAX_LEN (1024)
|
||||
|
||||
/*
|
||||
* This only guaranteed be enough for current krb5 des-cbc-crc . We might
|
||||
* adjust this when new enc type or mech added in.
|
||||
*/
|
||||
#define GSS_PRIVBUF_PREFIX_LEN (32)
|
||||
#define GSS_PRIVBUF_SUFFIX_LEN (32)
|
||||
|
||||
static inline
|
||||
struct gss_svc_reqctx *gss_svc_ctx2reqctx(struct ptlrpc_svc_ctx *ctx)
|
||||
{
|
||||
LASSERT(ctx);
|
||||
return container_of(ctx, struct gss_svc_reqctx, src_base);
|
||||
}
|
||||
|
||||
static inline
|
||||
struct gss_svc_ctx *gss_svc_ctx2gssctx(struct ptlrpc_svc_ctx *ctx)
|
||||
{
|
||||
LASSERT(ctx);
|
||||
return gss_svc_ctx2reqctx(ctx)->src_ctx;
|
||||
}
|
||||
|
||||
/* sec_gss.c */
|
||||
int gss_cli_ctx_match(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred);
|
||||
int gss_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize);
|
||||
int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
|
||||
int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
|
||||
int gss_cli_ctx_seal(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
|
||||
int gss_cli_ctx_unseal(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
|
||||
|
||||
int gss_sec_install_rctx(struct obd_import *imp, struct ptlrpc_sec *sec,
|
||||
struct ptlrpc_cli_ctx *ctx);
|
||||
int gss_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
|
||||
int msgsize);
|
||||
void gss_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
|
||||
int gss_alloc_repbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
|
||||
int msgsize);
|
||||
void gss_free_repbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
|
||||
int gss_enlarge_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
|
||||
int segment, int newsize);
|
||||
|
||||
int gss_svc_accept(struct ptlrpc_sec_policy *policy,
|
||||
struct ptlrpc_request *req);
|
||||
void gss_svc_invalidate_ctx(struct ptlrpc_svc_ctx *svc_ctx);
|
||||
int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen);
|
||||
int gss_svc_authorize(struct ptlrpc_request *req);
|
||||
void gss_svc_free_rs(struct ptlrpc_reply_state *rs);
|
||||
void gss_svc_free_ctx(struct ptlrpc_svc_ctx *ctx);
|
||||
|
||||
int cli_ctx_expire(struct ptlrpc_cli_ctx *ctx);
|
||||
int cli_ctx_check_death(struct ptlrpc_cli_ctx *ctx);
|
||||
|
||||
int gss_copy_rvc_cli_ctx(struct ptlrpc_cli_ctx *cli_ctx,
|
||||
struct ptlrpc_svc_ctx *svc_ctx);
|
||||
|
||||
struct gss_header *gss_swab_header(struct lustre_msg *msg, int segment,
|
||||
int swabbed);
|
||||
netobj_t *gss_swab_netobj(struct lustre_msg *msg, int segment);
|
||||
|
||||
void gss_cli_ctx_uptodate(struct gss_cli_ctx *gctx);
|
||||
int gss_pack_err_notify(struct ptlrpc_request *req, __u32 major, __u32 minor);
|
||||
int gss_check_seq_num(struct gss_svc_seq_data *sd, __u32 seq_num, int set);
|
||||
|
||||
int gss_sec_create_common(struct gss_sec *gsec,
|
||||
struct ptlrpc_sec_policy *policy,
|
||||
struct obd_import *imp,
|
||||
struct ptlrpc_svc_ctx *ctx,
|
||||
struct sptlrpc_flavor *sf);
|
||||
void gss_sec_destroy_common(struct gss_sec *gsec);
|
||||
void gss_sec_kill(struct ptlrpc_sec *sec);
|
||||
|
||||
int gss_cli_ctx_init_common(struct ptlrpc_sec *sec,
|
||||
struct ptlrpc_cli_ctx *ctx,
|
||||
struct ptlrpc_ctx_ops *ctxops,
|
||||
struct vfs_cred *vcred);
|
||||
int gss_cli_ctx_fini_common(struct ptlrpc_sec *sec,
|
||||
struct ptlrpc_cli_ctx *ctx);
|
||||
|
||||
void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize);
|
||||
|
||||
/* gss_keyring.c */
|
||||
int __init gss_init_keyring(void);
|
||||
void __exit gss_exit_keyring(void);
|
||||
|
||||
/* gss_pipefs.c */
|
||||
int __init gss_init_pipefs(void);
|
||||
void __exit gss_exit_pipefs(void);
|
||||
|
||||
/* gss_bulk.c */
|
||||
int gss_cli_prep_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
|
||||
struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
|
||||
struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
int gss_svc_prep_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
int gss_svc_wrap_bulk(struct ptlrpc_request *req,
|
||||
struct ptlrpc_bulk_desc *desc);
|
||||
|
||||
/* gss_mech_switch.c */
|
||||
int init_kerberos_module(void);
|
||||
void cleanup_kerberos_module(void);
|
||||
|
||||
/* gss_generic_token.c */
|
||||
int g_token_size(rawobj_t *mech, unsigned int body_size);
|
||||
void g_make_token_header(rawobj_t *mech, int body_size, unsigned char **buf);
|
||||
__u32 g_verify_token_header(rawobj_t *mech, int *body_size,
|
||||
unsigned char **buf_in, int toksize);
|
||||
|
||||
|
||||
/* gss_cli_upcall.c */
|
||||
int gss_do_ctx_init_rpc(char *buffer, unsigned long count);
|
||||
int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx);
|
||||
|
||||
int __init gss_init_cli_upcall(void);
|
||||
void __exit gss_exit_cli_upcall(void);
|
||||
|
||||
/* gss_svc_upcall.c */
|
||||
__u64 gss_get_next_ctx_index(void);
|
||||
int gss_svc_upcall_install_rvs_ctx(struct obd_import *imp,
|
||||
struct gss_sec *gsec,
|
||||
struct gss_cli_ctx *gctx);
|
||||
int gss_svc_upcall_expire_rvs_ctx(rawobj_t *handle);
|
||||
int gss_svc_upcall_dup_handle(rawobj_t *handle, struct gss_svc_ctx *ctx);
|
||||
int gss_svc_upcall_update_sequence(rawobj_t *handle, __u32 seq);
|
||||
int gss_svc_upcall_handle_init(struct ptlrpc_request *req,
|
||||
struct gss_svc_reqctx *grctx,
|
||||
struct gss_wire_ctx *gw,
|
||||
struct obd_device *target,
|
||||
__u32 lustre_svc,
|
||||
rawobj_t *rvs_hdl,
|
||||
rawobj_t *in_token);
|
||||
struct gss_svc_ctx *gss_svc_upcall_get_ctx(struct ptlrpc_request *req,
|
||||
struct gss_wire_ctx *gw);
|
||||
void gss_svc_upcall_put_ctx(struct gss_svc_ctx *ctx);
|
||||
void gss_svc_upcall_destroy_ctx(struct gss_svc_ctx *ctx);
|
||||
|
||||
int __init gss_init_svc_upcall(void);
|
||||
void __exit gss_exit_svc_upcall(void);
|
||||
|
||||
/* lproc_gss.c */
|
||||
void gss_stat_oos_record_cli(int behind);
|
||||
void gss_stat_oos_record_svc(int phase, int replay);
|
||||
|
||||
int __init gss_init_lproc(void);
|
||||
void __exit gss_exit_lproc(void);
|
||||
|
||||
/* gss_krb5_mech.c */
|
||||
int __init init_kerberos_module(void);
|
||||
void __exit cleanup_kerberos_module(void);
|
||||
|
||||
|
||||
/* debug */
|
||||
static inline
|
||||
void __dbg_memdump(char *name, void *ptr, int size)
|
||||
{
|
||||
char *buf, *p = (char *) ptr;
|
||||
int bufsize = size * 2 + 1, i;
|
||||
|
||||
OBD_ALLOC(buf, bufsize);
|
||||
if (!buf) {
|
||||
CDEBUG(D_ERROR, "DUMP ERROR: can't alloc %d bytes\n", bufsize);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
sprintf(&buf[i+i], "%02x", (__u8) p[i]);
|
||||
buf[size + size] = '\0';
|
||||
LCONSOLE_INFO("DUMP %s@%p(%d): %s\n", name, ptr, size, buf);
|
||||
OBD_FREE(buf, bufsize);
|
||||
}
|
||||
|
||||
#endif /* __PTLRPC_GSS_GSS_INTERNAL_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Modifications for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* linux/include/linux/sunrpc/gss_krb5_types.h
|
||||
*
|
||||
* Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
|
||||
* lib/gssapi/krb5/gssapiP_krb5.h, and others
|
||||
*
|
||||
* Copyright (c) 2000 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Andy Adamson <andros@umich.edu>
|
||||
* Bruce Fields <bfields@umich.edu>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1995 by the Massachusetts Institute of Technology.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Export of this software from the United States of America may
|
||||
* require a specific license from the United States Government.
|
||||
* It is the responsibility of any person or organization contemplating
|
||||
* export to obtain such a license before exporting.
|
||||
*
|
||||
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
* distribute this software and its documentation for any purpose and
|
||||
* without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright notice and
|
||||
* this permission notice appear in supporting documentation, and that
|
||||
* the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
* to distribution of the software without specific, written prior
|
||||
* permission. Furthermore if you modify this software you must label
|
||||
* your software as modified software and not distribute it in such a
|
||||
* fashion that it might be confused with the original M.I.T. software.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PTLRPC_GSS_KRB5_H
|
||||
#define PTLRPC_GSS_KRB5_H
|
||||
|
||||
/*
|
||||
* RFC 4142
|
||||
*/
|
||||
|
||||
#define KG_USAGE_ACCEPTOR_SEAL 22
|
||||
#define KG_USAGE_ACCEPTOR_SIGN 23
|
||||
#define KG_USAGE_INITIATOR_SEAL 24
|
||||
#define KG_USAGE_INITIATOR_SIGN 25
|
||||
|
||||
#define KG_TOK_MIC_MSG 0x0404
|
||||
#define KG_TOK_WRAP_MSG 0x0504
|
||||
|
||||
#define FLAG_SENDER_IS_ACCEPTOR 0x01
|
||||
#define FLAG_WRAP_CONFIDENTIAL 0x02
|
||||
#define FLAG_ACCEPTOR_SUBKEY 0x04
|
||||
|
||||
struct krb5_header {
|
||||
__u16 kh_tok_id; /* token id */
|
||||
__u8 kh_flags; /* acceptor flags */
|
||||
__u8 kh_filler; /* 0xff */
|
||||
__u16 kh_ec; /* extra count */
|
||||
__u16 kh_rrc; /* right rotation count */
|
||||
__u64 kh_seq; /* sequence number */
|
||||
__u8 kh_cksum[0]; /* checksum */
|
||||
};
|
||||
|
||||
struct krb5_keyblock {
|
||||
rawobj_t kb_key;
|
||||
struct ll_crypto_cipher *kb_tfm;
|
||||
};
|
||||
|
||||
struct krb5_ctx {
|
||||
unsigned int kc_initiate:1,
|
||||
kc_cfx:1,
|
||||
kc_seed_init:1,
|
||||
kc_have_acceptor_subkey:1;
|
||||
__s32 kc_endtime;
|
||||
__u8 kc_seed[16];
|
||||
__u64 kc_seq_send;
|
||||
__u64 kc_seq_recv;
|
||||
__u32 kc_enctype;
|
||||
struct krb5_keyblock kc_keye; /* encryption */
|
||||
struct krb5_keyblock kc_keyi; /* integrity */
|
||||
struct krb5_keyblock kc_keyc; /* checksum */
|
||||
rawobj_t kc_mech_used;
|
||||
};
|
||||
|
||||
enum sgn_alg {
|
||||
SGN_ALG_DES_MAC_MD5 = 0x0000,
|
||||
SGN_ALG_MD2_5 = 0x0001,
|
||||
SGN_ALG_DES_MAC = 0x0002,
|
||||
SGN_ALG_3 = 0x0003, /* not published */
|
||||
SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
|
||||
SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
|
||||
};
|
||||
|
||||
enum seal_alg {
|
||||
SEAL_ALG_NONE = 0xffff,
|
||||
SEAL_ALG_DES = 0x0000,
|
||||
SEAL_ALG_1 = 0x0001, /* not published */
|
||||
SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
|
||||
SEAL_ALG_DES3KD = 0x0002
|
||||
};
|
||||
|
||||
#define CKSUMTYPE_CRC32 0x0001
|
||||
#define CKSUMTYPE_RSA_MD4 0x0002
|
||||
#define CKSUMTYPE_RSA_MD4_DES 0x0003
|
||||
#define CKSUMTYPE_DESCBC 0x0004
|
||||
/* des-mac-k */
|
||||
/* rsa-md4-des-k */
|
||||
#define CKSUMTYPE_RSA_MD5 0x0007
|
||||
#define CKSUMTYPE_RSA_MD5_DES 0x0008
|
||||
#define CKSUMTYPE_NIST_SHA 0x0009
|
||||
#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
|
||||
#define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f
|
||||
#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010
|
||||
#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138
|
||||
|
||||
/* from gssapi_err_krb5.h */
|
||||
#define KG_CCACHE_NOMATCH (39756032L)
|
||||
#define KG_KEYTAB_NOMATCH (39756033L)
|
||||
#define KG_TGT_MISSING (39756034L)
|
||||
#define KG_NO_SUBKEY (39756035L)
|
||||
#define KG_CONTEXT_ESTABLISHED (39756036L)
|
||||
#define KG_BAD_SIGN_TYPE (39756037L)
|
||||
#define KG_BAD_LENGTH (39756038L)
|
||||
#define KG_CTX_INCOMPLETE (39756039L)
|
||||
#define KG_CONTEXT (39756040L)
|
||||
#define KG_CRED (39756041L)
|
||||
#define KG_ENC_DESC (39756042L)
|
||||
#define KG_BAD_SEQ (39756043L)
|
||||
#define KG_EMPTY_CCACHE (39756044L)
|
||||
#define KG_NO_CTYPES (39756045L)
|
||||
|
||||
/* per Kerberos v5 protocol spec crypto types from the wire.
|
||||
* these get mapped to linux kernel crypto routines.
|
||||
*/
|
||||
#define ENCTYPE_NULL 0x0000
|
||||
#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
|
||||
#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
|
||||
#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
|
||||
#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
|
||||
/* XXX deprecated? */
|
||||
#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
|
||||
#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
|
||||
#define ENCTYPE_DES_HMAC_SHA1 0x0008
|
||||
#define ENCTYPE_DES3_CBC_SHA1 0x0010
|
||||
#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
|
||||
#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
|
||||
#define ENCTYPE_ARCFOUR_HMAC 0x0017
|
||||
#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
|
||||
#define ENCTYPE_UNKNOWN 0x01ff
|
||||
|
||||
#endif /* PTLRPC_GSS_KRB5_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,358 +0,0 @@
|
||||
/*
|
||||
* Modifications for Lustre
|
||||
*
|
||||
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2012, Intel Corporation.
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* linux/net/sunrpc/gss_mech_switch.c
|
||||
*
|
||||
* Copyright (c) 2001 The Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* J. Bruce Fields <bfields@umich.edu>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define DEBUG_SUBSYSTEM S_SEC
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <obd.h>
|
||||
#include <obd_class.h>
|
||||
#include <obd_support.h>
|
||||
#include <lustre/lustre_idl.h>
|
||||
#include <lustre_net.h>
|
||||
#include <lustre_import.h>
|
||||
#include <lustre_sec.h>
|
||||
|
||||
#include "gss_err.h"
|
||||
#include "gss_internal.h"
|
||||
#include "gss_api.h"
|
||||
|
||||
static LIST_HEAD(registered_mechs);
|
||||
static DEFINE_SPINLOCK(registered_mechs_lock);
|
||||
|
||||
int lgss_mech_register(struct gss_api_mech *gm)
|
||||
{
|
||||
spin_lock(®istered_mechs_lock);
|
||||
list_add(&gm->gm_list, ®istered_mechs);
|
||||
spin_unlock(®istered_mechs_lock);
|
||||
CWARN("Register %s mechanism\n", gm->gm_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lgss_mech_unregister(struct gss_api_mech *gm)
|
||||
{
|
||||
spin_lock(®istered_mechs_lock);
|
||||
list_del(&gm->gm_list);
|
||||
spin_unlock(®istered_mechs_lock);
|
||||
CWARN("Unregister %s mechanism\n", gm->gm_name);
|
||||
}
|
||||
|
||||
|
||||
struct gss_api_mech *lgss_mech_get(struct gss_api_mech *gm)
|
||||
{
|
||||
__module_get(gm->gm_owner);
|
||||
return gm;
|
||||
}
|
||||
|
||||
struct gss_api_mech *lgss_name_to_mech(char *name)
|
||||
{
|
||||
struct gss_api_mech *pos, *gm = NULL;
|
||||
|
||||
spin_lock(®istered_mechs_lock);
|
||||
list_for_each_entry(pos, ®istered_mechs, gm_list) {
|
||||
if (0 == strcmp(name, pos->gm_name)) {
|
||||
if (!try_module_get(pos->gm_owner))
|
||||
continue;
|
||||
gm = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(®istered_mechs_lock);
|
||||
return gm;
|
||||
|
||||
}
|
||||
|
||||
static inline
|
||||
int mech_supports_subflavor(struct gss_api_mech *gm, __u32 subflavor)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gm->gm_sf_num; i++) {
|
||||
if (gm->gm_sfs[i].sf_subflavor == subflavor)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct gss_api_mech *lgss_subflavor_to_mech(__u32 subflavor)
|
||||
{
|
||||
struct gss_api_mech *pos, *gm = NULL;
|
||||
|
||||
spin_lock(®istered_mechs_lock);
|
||||
list_for_each_entry(pos, ®istered_mechs, gm_list) {
|
||||
if (!try_module_get(pos->gm_owner))
|
||||
continue;
|
||||
if (!mech_supports_subflavor(pos, subflavor)) {
|
||||
module_put(pos->gm_owner);
|
||||
continue;
|
||||
}
|
||||
gm = pos;
|
||||
break;
|
||||
}
|
||||
spin_unlock(®istered_mechs_lock);
|
||||
return gm;
|
||||
}
|
||||
|
||||
void lgss_mech_put(struct gss_api_mech *gm)
|
||||
{
|
||||
module_put(gm->gm_owner);
|
||||
}
|
||||
|
||||
/* The mech could probably be determined from the token instead, but it's just
|
||||
* as easy for now to pass it in. */
|
||||
__u32 lgss_import_sec_context(rawobj_t *input_token,
|
||||
struct gss_api_mech *mech,
|
||||
struct gss_ctx **ctx_id)
|
||||
{
|
||||
OBD_ALLOC_PTR(*ctx_id);
|
||||
if (*ctx_id == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
(*ctx_id)->mech_type = lgss_mech_get(mech);
|
||||
|
||||
LASSERT(mech);
|
||||
LASSERT(mech->gm_ops);
|
||||
LASSERT(mech->gm_ops->gss_import_sec_context);
|
||||
return mech->gm_ops->gss_import_sec_context(input_token, *ctx_id);
|
||||
}
|
||||
|
||||
__u32 lgss_copy_reverse_context(struct gss_ctx *ctx_id,
|
||||
struct gss_ctx **ctx_id_new)
|
||||
{
|
||||
struct gss_api_mech *mech = ctx_id->mech_type;
|
||||
__u32 major;
|
||||
|
||||
LASSERT(mech);
|
||||
|
||||
OBD_ALLOC_PTR(*ctx_id_new);
|
||||
if (*ctx_id_new == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
(*ctx_id_new)->mech_type = lgss_mech_get(mech);
|
||||
|
||||
LASSERT(mech);
|
||||
LASSERT(mech->gm_ops);
|
||||
LASSERT(mech->gm_ops->gss_copy_reverse_context);
|
||||
|
||||
major = mech->gm_ops->gss_copy_reverse_context(ctx_id, *ctx_id_new);
|
||||
if (major != GSS_S_COMPLETE) {
|
||||
lgss_mech_put(mech);
|
||||
OBD_FREE_PTR(*ctx_id_new);
|
||||
*ctx_id_new = NULL;
|
||||
}
|
||||
return major;
|
||||
}
|
||||
|
||||
/*
|
||||
* this interface is much simplified, currently we only need endtime.
|
||||
*/
|
||||
__u32 lgss_inquire_context(struct gss_ctx *context_handle,
|
||||
unsigned long *endtime)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_inquire_context);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_inquire_context(context_handle,
|
||||
endtime);
|
||||
}
|
||||
|
||||
/* gss_get_mic: compute a mic over message and return mic_token. */
|
||||
__u32 lgss_get_mic(struct gss_ctx *context_handle,
|
||||
int msgcnt,
|
||||
rawobj_t *msg,
|
||||
int iovcnt,
|
||||
lnet_kiov_t *iovs,
|
||||
rawobj_t *mic_token)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_get_mic);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_get_mic(context_handle,
|
||||
msgcnt,
|
||||
msg,
|
||||
iovcnt,
|
||||
iovs,
|
||||
mic_token);
|
||||
}
|
||||
|
||||
/* gss_verify_mic: check whether the provided mic_token verifies message. */
|
||||
__u32 lgss_verify_mic(struct gss_ctx *context_handle,
|
||||
int msgcnt,
|
||||
rawobj_t *msg,
|
||||
int iovcnt,
|
||||
lnet_kiov_t *iovs,
|
||||
rawobj_t *mic_token)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_verify_mic);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_verify_mic(context_handle,
|
||||
msgcnt,
|
||||
msg,
|
||||
iovcnt,
|
||||
iovs,
|
||||
mic_token);
|
||||
}
|
||||
|
||||
__u32 lgss_wrap(struct gss_ctx *context_handle,
|
||||
rawobj_t *gsshdr,
|
||||
rawobj_t *msg,
|
||||
int msg_buflen,
|
||||
rawobj_t *out_token)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_wrap);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_wrap(context_handle, gsshdr, msg, msg_buflen, out_token);
|
||||
}
|
||||
|
||||
__u32 lgss_unwrap(struct gss_ctx *context_handle,
|
||||
rawobj_t *gsshdr,
|
||||
rawobj_t *token,
|
||||
rawobj_t *out_msg)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_unwrap);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_unwrap(context_handle, gsshdr, token, out_msg);
|
||||
}
|
||||
|
||||
|
||||
__u32 lgss_prep_bulk(struct gss_ctx *context_handle,
|
||||
struct ptlrpc_bulk_desc *desc)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_prep_bulk);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_prep_bulk(context_handle, desc);
|
||||
}
|
||||
|
||||
__u32 lgss_wrap_bulk(struct gss_ctx *context_handle,
|
||||
struct ptlrpc_bulk_desc *desc,
|
||||
rawobj_t *token,
|
||||
int adj_nob)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_wrap_bulk);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_wrap_bulk(context_handle, desc, token, adj_nob);
|
||||
}
|
||||
|
||||
__u32 lgss_unwrap_bulk(struct gss_ctx *context_handle,
|
||||
struct ptlrpc_bulk_desc *desc,
|
||||
rawobj_t *token,
|
||||
int adj_nob)
|
||||
{
|
||||
LASSERT(context_handle);
|
||||
LASSERT(context_handle->mech_type);
|
||||
LASSERT(context_handle->mech_type->gm_ops);
|
||||
LASSERT(context_handle->mech_type->gm_ops->gss_unwrap_bulk);
|
||||
|
||||
return context_handle->mech_type->gm_ops
|
||||
->gss_unwrap_bulk(context_handle, desc, token, adj_nob);
|
||||
}
|
||||
|
||||
/* gss_delete_sec_context: free all resources associated with context_handle.
|
||||
* Note this differs from the RFC 2744-specified prototype in that we don't
|
||||
* bother returning an output token, since it would never be used anyway. */
|
||||
|
||||
__u32 lgss_delete_sec_context(struct gss_ctx **context_handle)
|
||||
{
|
||||
struct gss_api_mech *mech;
|
||||
|
||||
CDEBUG(D_SEC, "deleting %p\n", *context_handle);
|
||||
|
||||
if (!*context_handle)
|
||||
return(GSS_S_NO_CONTEXT);
|
||||
|
||||
mech = (*context_handle)->mech_type;
|
||||
if ((*context_handle)->internal_ctx_id != 0) {
|
||||
LASSERT(mech);
|
||||
LASSERT(mech->gm_ops);
|
||||
LASSERT(mech->gm_ops->gss_delete_sec_context);
|
||||
mech->gm_ops->gss_delete_sec_context(
|
||||
(*context_handle)->internal_ctx_id);
|
||||
}
|
||||
if (mech)
|
||||
lgss_mech_put(mech);
|
||||
|
||||
OBD_FREE_PTR(*context_handle);
|
||||
*context_handle=NULL;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
int lgss_display(struct gss_ctx *ctx,
|
||||
char *buf,
|
||||
int bufsize)
|
||||
{
|
||||
LASSERT(ctx);
|
||||
LASSERT(ctx->mech_type);
|
||||
LASSERT(ctx->mech_type->gm_ops);
|
||||
LASSERT(ctx->mech_type->gm_ops->gss_display);
|
||||
|
||||
return ctx->mech_type->gm_ops->gss_display(ctx, buf, bufsize);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,242 +0,0 @@
|
||||
/*
|
||||
* GPL HEADER START
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 2011, Intel Corporation.
|
||||
*/
|
||||
/*
|
||||
* This file is part of Lustre, http://www.lustre.org/
|
||||
* Lustre is a trademark of Sun Microsystems, Inc.
|
||||
*
|
||||
* lustre/ptlrpc/gss/gss_rawobj.c
|
||||
*
|
||||
* Author: Eric Mei <ericm@clusterfs.com>
|
||||
*/
|
||||
|
||||
#define DEBUG_SUBSYSTEM S_SEC
|
||||
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <obd.h>
|
||||
#include <obd_class.h>
|
||||
#include <obd_support.h>
|
||||
#include <lustre_sec.h>
|
||||
|
||||
#include "gss_internal.h"
|
||||
|
||||
int rawobj_empty(rawobj_t *obj)
|
||||
{
|
||||
LASSERT(equi(obj->len, obj->data));
|
||||
return (obj->len == 0);
|
||||
}
|
||||
|
||||
int rawobj_alloc(rawobj_t *obj, char *buf, int len)
|
||||
{
|
||||
LASSERT(obj);
|
||||
LASSERT(len >= 0);
|
||||
|
||||
obj->len = len;
|
||||
if (len) {
|
||||
OBD_ALLOC_LARGE(obj->data, len);
|
||||
if (!obj->data) {
|
||||
obj->len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(obj->data, buf, len);
|
||||
} else
|
||||
obj->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rawobj_free(rawobj_t *obj)
|
||||
{
|
||||
LASSERT(obj);
|
||||
|
||||
if (obj->len) {
|
||||
LASSERT(obj->data);
|
||||
OBD_FREE_LARGE(obj->data, obj->len);
|
||||
obj->len = 0;
|
||||
obj->data = NULL;
|
||||
} else
|
||||
LASSERT(!obj->data);
|
||||
}
|
||||
|
||||
int rawobj_equal(rawobj_t *a, rawobj_t *b)
|
||||
{
|
||||
LASSERT(a && b);
|
||||
|
||||
return (a->len == b->len &&
|
||||
(!a->len || !memcmp(a->data, b->data, a->len)));
|
||||
}
|
||||
|
||||
int rawobj_dup(rawobj_t *dest, rawobj_t *src)
|
||||
{
|
||||
LASSERT(src && dest);
|
||||
|
||||
dest->len = src->len;
|
||||
if (dest->len) {
|
||||
OBD_ALLOC_LARGE(dest->data, dest->len);
|
||||
if (!dest->data) {
|
||||
dest->len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(dest->data, src->data, dest->len);
|
||||
} else
|
||||
dest->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen)
|
||||
{
|
||||
__u32 len;
|
||||
|
||||
LASSERT(obj);
|
||||
LASSERT(buf);
|
||||
LASSERT(buflen);
|
||||
|
||||
len = cfs_size_round4(obj->len);
|
||||
|
||||
if (*buflen < 4 + len) {
|
||||
CERROR("buflen %u < %u\n", *buflen, 4 + len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*(*buf)++ = cpu_to_le32(obj->len);
|
||||
memcpy(*buf, obj->data, obj->len);
|
||||
*buf += (len >> 2);
|
||||
*buflen -= (4 + len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen,
|
||||
int alloc, int local)
|
||||
{
|
||||
__u32 len;
|
||||
|
||||
if (*buflen < sizeof(__u32)) {
|
||||
CERROR("buflen %u\n", *buflen);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
obj->len = *(*buf)++;
|
||||
if (!local)
|
||||
obj->len = le32_to_cpu(obj->len);
|
||||
*buflen -= sizeof(__u32);
|
||||
|
||||
if (!obj->len) {
|
||||
obj->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = local ? obj->len : cfs_size_round4(obj->len);
|
||||
if (*buflen < len) {
|
||||
CERROR("buflen %u < %u\n", *buflen, len);
|
||||
obj->len = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!alloc)
|
||||
obj->data = (__u8 *) *buf;
|
||||
else {
|
||||
OBD_ALLOC_LARGE(obj->data, obj->len);
|
||||
if (!obj->data) {
|
||||
CERROR("fail to alloc %u bytes\n", obj->len);
|
||||
obj->len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(obj->data, *buf, obj->len);
|
||||
}
|
||||
|
||||
*((char **)buf) += len;
|
||||
*buflen -= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen)
|
||||
{
|
||||
return __rawobj_extract(obj, buf, buflen, 0, 0);
|
||||
}
|
||||
|
||||
int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
|
||||
{
|
||||
return __rawobj_extract(obj, buf, buflen, 1, 0);
|
||||
}
|
||||
|
||||
int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen)
|
||||
{
|
||||
return __rawobj_extract(obj, buf, buflen, 0, 1);
|
||||
}
|
||||
|
||||
int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
|
||||
{
|
||||
return __rawobj_extract(obj, buf, buflen, 1, 1);
|
||||
}
|
||||
|
||||
int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj)
|
||||
{
|
||||
rawobj->len = netobj->len;
|
||||
rawobj->data = netobj->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rawobj_from_netobj_alloc(rawobj_t *rawobj, netobj_t *netobj)
|
||||
{
|
||||
rawobj->len = 0;
|
||||
rawobj->data = NULL;
|
||||
|
||||
if (netobj->len == 0)
|
||||
return 0;
|
||||
|
||||
OBD_ALLOC_LARGE(rawobj->data, netobj->len);
|
||||
if (rawobj->data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rawobj->len = netobj->len;
|
||||
memcpy(rawobj->data, netobj->data, netobj->len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************
|
||||
* misc more *
|
||||
****************************************/
|
||||
|
||||
int buffer_extract_bytes(const void **buf, __u32 *buflen,
|
||||
void *res, __u32 reslen)
|
||||
{
|
||||
if (*buflen < reslen) {
|
||||
CERROR("buflen %u < %u\n", *buflen, reslen);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(res, *buf, reslen);
|
||||
*buf += reslen;
|
||||
*buflen -= reslen;
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* GPL HEADER START
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 2012, Intel Corporation.
|
||||
*/
|
||||
/*
|
||||
* This file is part of Lustre, http://www.lustre.org/
|
||||
* Lustre is a trademark of Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#define DEBUG_SUBSYSTEM S_SEC
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <obd.h>
|
||||
#include <obd_class.h>
|
||||
#include <obd_support.h>
|
||||
#include <lustre/lustre_idl.h>
|
||||
#include <lustre_net.h>
|
||||
#include <lustre_import.h>
|
||||
#include <lprocfs_status.h>
|
||||
#include <lustre_sec.h>
|
||||
|
||||
#include "gss_err.h"
|
||||
#include "gss_internal.h"
|
||||
#include "gss_api.h"
|
||||
|
||||
static struct proc_dir_entry *gss_proc_root = NULL;
|
||||
static struct proc_dir_entry *gss_proc_lk = NULL;
|
||||
|
||||
/*
|
||||
* statistic of "out-of-sequence-window"
|
||||
*/
|
||||
static struct {
|
||||
spinlock_t oos_lock;
|
||||
atomic_t oos_cli_count; /* client occurrence */
|
||||
int oos_cli_behind; /* client max seqs behind */
|
||||
atomic_t oos_svc_replay[3]; /* server replay detected */
|
||||
atomic_t oos_svc_pass[3]; /* server verified ok */
|
||||
} gss_stat_oos = {
|
||||
.oos_cli_count = ATOMIC_INIT(0),
|
||||
.oos_cli_behind = 0,
|
||||
.oos_svc_replay = { ATOMIC_INIT(0), },
|
||||
.oos_svc_pass = { ATOMIC_INIT(0), },
|
||||
};
|
||||
|
||||
void gss_stat_oos_record_cli(int behind)
|
||||
{
|
||||
atomic_inc(&gss_stat_oos.oos_cli_count);
|
||||
|
||||
spin_lock(&gss_stat_oos.oos_lock);
|
||||
if (behind > gss_stat_oos.oos_cli_behind)
|
||||
gss_stat_oos.oos_cli_behind = behind;
|
||||
spin_unlock(&gss_stat_oos.oos_lock);
|
||||
}
|
||||
|
||||
void gss_stat_oos_record_svc(int phase, int replay)
|
||||
{
|
||||
LASSERT(phase >= 0 && phase <= 2);
|
||||
|
||||
if (replay)
|
||||
atomic_inc(&gss_stat_oos.oos_svc_replay[phase]);
|
||||
else
|
||||
atomic_inc(&gss_stat_oos.oos_svc_pass[phase]);
|
||||
}
|
||||
|
||||
static int gss_proc_oos_seq_show(struct seq_file *m, void *v)
|
||||
{
|
||||
return seq_printf(m,
|
||||
"seqwin: %u\n"
|
||||
"backwin: %u\n"
|
||||
"client fall behind seqwin\n"
|
||||
" occurrence: %d\n"
|
||||
" max seq behind: %d\n"
|
||||
"server replay detected:\n"
|
||||
" phase 0: %d\n"
|
||||
" phase 1: %d\n"
|
||||
" phase 2: %d\n"
|
||||
"server verify ok:\n"
|
||||
" phase 2: %d\n",
|
||||
GSS_SEQ_WIN_MAIN,
|
||||
GSS_SEQ_WIN_BACK,
|
||||
atomic_read(&gss_stat_oos.oos_cli_count),
|
||||
gss_stat_oos.oos_cli_behind,
|
||||
atomic_read(&gss_stat_oos.oos_svc_replay[0]),
|
||||
atomic_read(&gss_stat_oos.oos_svc_replay[1]),
|
||||
atomic_read(&gss_stat_oos.oos_svc_replay[2]),
|
||||
atomic_read(&gss_stat_oos.oos_svc_pass[2]));
|
||||
}
|
||||
LPROC_SEQ_FOPS_RO(gss_proc_oos);
|
||||
|
||||
static int gss_proc_write_secinit(struct file *file, const char *buffer,
|
||||
size_t count, off_t *off)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = gss_do_ctx_init_rpc((char *) buffer, count);
|
||||
if (rc) {
|
||||
LASSERT(rc < 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations gss_proc_secinit = {
|
||||
.write = gss_proc_write_secinit,
|
||||
};
|
||||
|
||||
static struct lprocfs_vars gss_lprocfs_vars[] = {
|
||||
{ "replays", &gss_proc_oos_fops },
|
||||
{ "init_channel", &gss_proc_secinit, NULL, 0222 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* for userspace helper lgss_keyring.
|
||||
*
|
||||
* debug_level: [0, 4], defined in utils/gss/lgss_utils.h
|
||||
*/
|
||||
static int gss_lk_debug_level = 1;
|
||||
|
||||
static int gss_lk_proc_dl_seq_show(struct seq_file *m, void *v)
|
||||
{
|
||||
return seq_printf(m, "%u\n", gss_lk_debug_level);
|
||||
}
|
||||
|
||||
static int gss_lk_proc_dl_seq_write(struct file *file, const char *buffer,
|
||||
size_t count, off_t *off)
|
||||
{
|
||||
int val, rc;
|
||||
|
||||
rc = lprocfs_write_helper(buffer, count, &val);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (val < 0 || val > 4)
|
||||
return -ERANGE;
|
||||
|
||||
gss_lk_debug_level = val;
|
||||
return count;
|
||||
}
|
||||
LPROC_SEQ_FOPS(gss_lk_proc_dl);
|
||||
|
||||
static struct lprocfs_vars gss_lk_lprocfs_vars[] = {
|
||||
{ "debug_level", &gss_lk_proc_dl_fops },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void gss_exit_lproc(void)
|
||||
{
|
||||
if (gss_proc_lk) {
|
||||
lprocfs_remove(&gss_proc_lk);
|
||||
gss_proc_lk = NULL;
|
||||
}
|
||||
|
||||
if (gss_proc_root) {
|
||||
lprocfs_remove(&gss_proc_root);
|
||||
gss_proc_root = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int gss_init_lproc(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
spin_lock_init(&gss_stat_oos.oos_lock);
|
||||
|
||||
gss_proc_root = lprocfs_register("gss", sptlrpc_proc_root,
|
||||
gss_lprocfs_vars, NULL);
|
||||
if (IS_ERR(gss_proc_root)) {
|
||||
rc = PTR_ERR(gss_proc_root);
|
||||
gss_proc_root = NULL;
|
||||
GOTO(err_out, rc);
|
||||
}
|
||||
|
||||
gss_proc_lk = lprocfs_register("lgss_keyring", gss_proc_root,
|
||||
gss_lk_lprocfs_vars, NULL);
|
||||
if (IS_ERR(gss_proc_lk)) {
|
||||
rc = PTR_ERR(gss_proc_lk);
|
||||
gss_proc_lk = NULL;
|
||||
GOTO(err_out, rc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
CERROR("failed to initialize gss lproc entries: %d\n", rc);
|
||||
gss_exit_lproc();
|
||||
return rc;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user