Whamcloud - gitweb
b=15266
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_rawobj.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/ptlrpc/gss/gss_rawobj.c
37  *
38  * Author: Eric Mei <ericm@clusterfs.com>
39  */
40
41 #ifndef EXPORT_SYMTAB
42 # define EXPORT_SYMTAB
43 #endif
44 #define DEBUG_SUBSYSTEM S_SEC
45
46 #include <linux/mutex.h>
47
48 #include <obd.h>
49 #include <obd_class.h>
50 #include <obd_support.h>
51 #include <lustre_sec.h>
52
53 #include "gss_internal.h"
54
55 int rawobj_empty(rawobj_t *obj)
56 {
57         LASSERT(equi(obj->len, obj->data));
58         return (obj->len == 0);
59 }
60
61 int rawobj_alloc(rawobj_t *obj, char *buf, int len)
62 {
63         LASSERT(obj);
64         LASSERT(len >= 0);
65
66         obj->len = len;
67         if (len) {
68                 OBD_ALLOC(obj->data, len);
69                 if (!obj->data) {
70                         obj->len = 0;
71                         RETURN(-ENOMEM);
72                 }
73                 memcpy(obj->data, buf, len);
74         } else
75                 obj->data = NULL;
76         return 0;
77 }
78
79 void rawobj_free(rawobj_t *obj)
80 {
81         LASSERT(obj);
82
83         if (obj->len) {
84                 LASSERT(obj->data);
85                 OBD_FREE(obj->data, obj->len);
86                 obj->len = 0;
87                 obj->data = NULL;
88         } else
89                 LASSERT(!obj->data);
90 }
91
92 int rawobj_equal(rawobj_t *a, rawobj_t *b)
93 {
94         LASSERT(a && b);
95
96         return (a->len == b->len &&
97                 (!a->len || !memcmp(a->data, b->data, a->len)));
98 }
99
100 int rawobj_dup(rawobj_t *dest, rawobj_t *src)
101 {
102         LASSERT(src && dest);
103
104         dest->len = src->len;
105         if (dest->len) {
106                 OBD_ALLOC(dest->data, dest->len);
107                 if (!dest->data) {
108                         dest->len = 0;
109                         return -ENOMEM;
110                 }
111                 memcpy(dest->data, src->data, dest->len);
112         } else
113                 dest->data = NULL;
114         return 0;
115 }
116
117 int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen)
118 {
119         __u32 len;
120
121         LASSERT(obj);
122         LASSERT(buf);
123         LASSERT(buflen);
124
125         len = size_round4(obj->len);
126
127         if (*buflen < 4 + len) {
128                 CERROR("buflen %u <  %u\n", *buflen, 4 + len);
129                 return -EINVAL;
130         }
131
132         *(*buf)++ = cpu_to_le32(obj->len);
133         memcpy(*buf, obj->data, obj->len);
134         *buf += (len >> 2);
135         *buflen -= (4 + len);
136
137         return 0;
138 }
139
140 static int __rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen,
141                             int alloc, int local)
142 {
143         __u32 len;
144
145         if (*buflen < sizeof(__u32)) {
146                 CERROR("buflen %u\n", *buflen);
147                 return -EINVAL;
148         }
149
150         obj->len = *(*buf)++;
151         if (!local)
152                 obj->len = le32_to_cpu(obj->len);
153         *buflen -= sizeof(__u32);
154
155         if (!obj->len) {
156                 obj->data = NULL;
157                 return 0;
158         }
159
160         len = local ? obj->len : size_round4(obj->len);
161         if (*buflen < len) {
162                 CERROR("buflen %u < %u\n", *buflen, len);
163                 obj->len = 0;
164                 return -EINVAL;
165         }
166
167         if (!alloc)
168                 obj->data = (__u8 *) *buf;
169         else {
170                 OBD_ALLOC(obj->data, obj->len);
171                 if (!obj->data) {
172                         CERROR("fail to alloc %u bytes\n", obj->len);
173                         obj->len = 0;
174                         return -ENOMEM;
175                 }
176                 memcpy(obj->data, *buf, obj->len);
177         }
178
179         *((char **)buf) += len;
180         *buflen -= len;
181
182         return 0;
183 }
184
185 int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen)
186 {
187         return __rawobj_extract(obj, buf, buflen, 0, 0);
188 }
189
190 int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
191 {
192         return __rawobj_extract(obj, buf, buflen, 1, 0);
193 }
194
195 int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen)
196 {
197         return __rawobj_extract(obj, buf, buflen, 0, 1);
198 }
199
200 int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
201 {
202         return __rawobj_extract(obj, buf, buflen, 1, 1);
203 }
204
205 int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj)
206 {
207         rawobj->len = netobj->len;
208         rawobj->data = netobj->data;
209         return 0;
210 }
211
212 int rawobj_from_netobj_alloc(rawobj_t *rawobj, netobj_t *netobj)
213 {
214         rawobj->len = 0;
215         rawobj->data = NULL;
216
217         if (netobj->len == 0)
218                 return 0;
219                 
220         OBD_ALLOC(rawobj->data, netobj->len);
221         if (rawobj->data == NULL)
222                 return -ENOMEM;
223
224         rawobj->len = netobj->len;
225         memcpy(rawobj->data, netobj->data, netobj->len);
226         return 0;
227 }
228
229 /****************************************
230  * misc more                            *
231  ****************************************/
232
233 int buffer_extract_bytes(const void **buf, __u32 *buflen,
234                          void *res, __u32 reslen)
235 {
236         if (*buflen < reslen) {
237                 CERROR("buflen %u < %u\n", *buflen, reslen);
238                 return -EINVAL;
239         }
240
241         memcpy(res, *buf, reslen);
242         *buf += reslen;
243         *buflen -= reslen;
244         return 0;
245 }