/* * 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 */ #define DEBUG_SUBSYSTEM S_SEC #include #include #include #include #include #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; }