Whamcloud - gitweb
land b_colibri_devel on HEAD:
[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  * Copyright (C) 2004 Cluster File Systems, Inc.
5  *   Author: Eric Mei <ericm@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #ifndef EXPORT_SYMTAB
24 # define EXPORT_SYMTAB
25 #endif
26 #define DEBUG_SUBSYSTEM S_SEC
27
28 #include <linux/mutex.h>
29
30 #include <obd.h>
31 #include <obd_class.h>
32 #include <obd_support.h>
33 #include <lustre_sec.h>
34
35 #include "gss_internal.h"
36
37 int rawobj_empty(rawobj_t *obj)
38 {
39         LASSERT(equi(obj->len, obj->data));
40         return (obj->len == 0);
41 }
42
43 int rawobj_alloc(rawobj_t *obj, char *buf, int len)
44 {
45         LASSERT(obj);
46         LASSERT(len >= 0);
47
48         obj->len = len;
49         if (len) {
50                 OBD_ALLOC(obj->data, len);
51                 if (!obj->data) {
52                         obj->len = 0;
53                         RETURN(-ENOMEM);
54                 }
55                 memcpy(obj->data, buf, len);
56         } else
57                 obj->data = NULL;
58         return 0;
59 }
60
61 void rawobj_free(rawobj_t *obj)
62 {
63         LASSERT(obj);
64
65         if (obj->len) {
66                 LASSERT(obj->data);
67                 OBD_FREE(obj->data, obj->len);
68                 obj->len = 0;
69                 obj->data = NULL;
70         } else
71                 LASSERT(!obj->data);
72 }
73
74 int rawobj_equal(rawobj_t *a, rawobj_t *b)
75 {
76         LASSERT(a && b);
77
78         return (a->len == b->len &&
79                 (!a->len || !memcmp(a->data, b->data, a->len)));
80 }
81
82 int rawobj_dup(rawobj_t *dest, rawobj_t *src)
83 {
84         LASSERT(src && dest);
85
86         dest->len = src->len;
87         if (dest->len) {
88                 OBD_ALLOC(dest->data, dest->len);
89                 if (!dest->data) {
90                         dest->len = 0;
91                         return -ENOMEM;
92                 }
93                 memcpy(dest->data, src->data, dest->len);
94         } else
95                 dest->data = NULL;
96         return 0;
97 }
98
99 int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen)
100 {
101         __u32 len;
102
103         LASSERT(obj);
104         LASSERT(buf);
105         LASSERT(buflen);
106
107         len = size_round4(obj->len);
108
109         if (*buflen < 4 + len) {
110                 CERROR("buflen %u <  %u\n", *buflen, 4 + len);
111                 return -EINVAL;
112         }
113
114         *(*buf)++ = cpu_to_le32(obj->len);
115         memcpy(*buf, obj->data, obj->len);
116         *buf += (len >> 2);
117         *buflen -= (4 + len);
118
119         return 0;
120 }
121
122 static int __rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen,
123                             int alloc, int local)
124 {
125         __u32 len;
126
127         if (*buflen < sizeof(__u32)) {
128                 CERROR("buflen %u\n", *buflen);
129                 return -EINVAL;
130         }
131
132         obj->len = *(*buf)++;
133         if (!local)
134                 obj->len = le32_to_cpu(obj->len);
135         *buflen -= sizeof(__u32);
136
137         if (!obj->len) {
138                 obj->data = NULL;
139                 return 0;
140         }
141
142         len = local ? obj->len : size_round4(obj->len);
143         if (*buflen < len) {
144                 CERROR("buflen %u < %u\n", *buflen, len);
145                 obj->len = 0;
146                 return -EINVAL;
147         }
148
149         if (!alloc)
150                 obj->data = (__u8 *) *buf;
151         else {
152                 OBD_ALLOC(obj->data, obj->len);
153                 if (!obj->data) {
154                         CERROR("fail to alloc %u bytes\n", obj->len);
155                         obj->len = 0;
156                         return -ENOMEM;
157                 }
158                 memcpy(obj->data, *buf, obj->len);
159         }
160
161         *((char **)buf) += len;
162         *buflen -= len;
163
164         return 0;
165 }
166
167 int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen)
168 {
169         return __rawobj_extract(obj, buf, buflen, 0, 0);
170 }
171
172 int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
173 {
174         return __rawobj_extract(obj, buf, buflen, 1, 0);
175 }
176
177 int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen)
178 {
179         return __rawobj_extract(obj, buf, buflen, 0, 1);
180 }
181
182 int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
183 {
184         return __rawobj_extract(obj, buf, buflen, 1, 1);
185 }
186
187 int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj)
188 {
189         rawobj->len = netobj->len;
190         rawobj->data = netobj->data;
191         return 0;
192 }
193
194 int rawobj_from_netobj_alloc(rawobj_t *rawobj, netobj_t *netobj)
195 {
196         rawobj->len = 0;
197         rawobj->data = NULL;
198
199         if (netobj->len == 0)
200                 return 0;
201                 
202         OBD_ALLOC(rawobj->data, netobj->len);
203         if (rawobj->data == NULL)
204                 return -ENOMEM;
205
206         rawobj->len = netobj->len;
207         memcpy(rawobj->data, netobj->data, netobj->len);
208         return 0;
209 }
210
211 /****************************************
212  * misc more                            *
213  ****************************************/
214
215 int buffer_extract_bytes(const void **buf, __u32 *buflen,
216                          void *res, __u32 reslen)
217 {
218         if (*buflen < reslen) {
219                 CERROR("buflen %u < %u\n", *buflen, reslen);
220                 return -EINVAL;
221         }
222
223         memcpy(res, *buf, reslen);
224         *buf += reslen;
225         *buflen -= reslen;
226         return 0;
227 }