Whamcloud - gitweb
branch: 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_alloc(rawobj_t *obj, char *buf, int len)
38 {
39         LASSERT(obj);
40         LASSERT(len >= 0);
41
42         obj->len = len;
43         if (len) {
44                 OBD_ALLOC(obj->data, len);
45                 if (!obj->data) {
46                         obj->len = 0;
47                         RETURN(-ENOMEM);
48                 }
49                 memcpy(obj->data, buf, len);
50         } else
51                 obj->data = NULL;
52         return 0;
53 }
54
55 void rawobj_free(rawobj_t *obj)
56 {
57         LASSERT(obj);
58
59         if (obj->len) {
60                 LASSERT(obj->data);
61                 OBD_FREE(obj->data, obj->len);
62                 obj->len = 0;
63                 obj->data = NULL;
64         } else
65                 LASSERT(!obj->data);
66 }
67
68 int rawobj_equal(rawobj_t *a, rawobj_t *b)
69 {
70         LASSERT(a && b);
71
72         return (a->len == b->len &&
73                 (!a->len || !memcmp(a->data, b->data, a->len)));
74 }
75
76 int rawobj_dup(rawobj_t *dest, rawobj_t *src)
77 {
78         LASSERT(src && dest);
79
80         dest->len = src->len;
81         if (dest->len) {
82                 OBD_ALLOC(dest->data, dest->len);
83                 if (!dest->data) {
84                         dest->len = 0;
85                         return -ENOMEM;
86                 }
87                 memcpy(dest->data, src->data, dest->len);
88         } else
89                 dest->data = NULL;
90         return 0;
91 }
92
93 int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen)
94 {
95         __u32 len;
96
97         LASSERT(obj);
98         LASSERT(buf);
99         LASSERT(buflen);
100
101         len = size_round4(obj->len);
102
103         if (*buflen < 4 + len) {
104                 CERROR("buflen %u <  %u\n", *buflen, 4 + len);
105                 return -EINVAL;
106         }
107
108         *(*buf)++ = cpu_to_le32(obj->len);
109         memcpy(*buf, obj->data, obj->len);
110         *buf += (len >> 2);
111         *buflen -= (4 + len);
112
113         return 0;
114 }
115
116 static int __rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen,
117                             int alloc, int local)
118 {
119         __u32 len;
120
121         if (*buflen < sizeof(__u32)) {
122                 CERROR("buflen %u\n", *buflen);
123                 return -EINVAL;
124         }
125
126         obj->len = *(*buf)++;
127         if (!local)
128                 obj->len = le32_to_cpu(obj->len);
129         *buflen -= sizeof(__u32);
130
131         if (!obj->len) {
132                 obj->data = NULL;
133                 return 0;
134         }
135
136         len = local ? obj->len : size_round4(obj->len);
137         if (*buflen < len) {
138                 CERROR("buflen %u < %u\n", *buflen, len);
139                 obj->len = 0;
140                 return -EINVAL;
141         }
142
143         if (!alloc)
144                 obj->data = (__u8 *) *buf;
145         else {
146                 OBD_ALLOC(obj->data, obj->len);
147                 if (!obj->data) {
148                         CERROR("fail to alloc %u bytes\n", obj->len);
149                         obj->len = 0;
150                         return -ENOMEM;
151                 }
152                 memcpy(obj->data, *buf, obj->len);
153         }
154
155         *((char **)buf) += len;
156         *buflen -= len;
157
158         return 0;
159 }
160
161 int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen)
162 {
163         return __rawobj_extract(obj, buf, buflen, 0, 0);
164 }
165
166 int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
167 {
168         return __rawobj_extract(obj, buf, buflen, 1, 0);
169 }
170
171 int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen)
172 {
173         return __rawobj_extract(obj, buf, buflen, 0, 1);
174 }
175
176 int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
177 {
178         return __rawobj_extract(obj, buf, buflen, 1, 1);
179 }
180
181 int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj)
182 {
183         rawobj->len = netobj->len;
184         rawobj->data = netobj->data;
185         return 0;
186 }
187
188 int rawobj_from_netobj_alloc(rawobj_t *rawobj, netobj_t *netobj)
189 {
190         rawobj->len = 0;
191         rawobj->data = NULL;
192
193         if (netobj->len == 0)
194                 return 0;
195                 
196         OBD_ALLOC(rawobj->data, netobj->len);
197         if (rawobj->data == NULL)
198                 return -ENOMEM;
199
200         rawobj->len = netobj->len;
201         memcpy(rawobj->data, netobj->data, netobj->len);
202         return 0;
203 }
204
205 /****************************************
206  * misc more                            *
207  ****************************************/
208
209 int buffer_extract_bytes(const void **buf, __u32 *buflen,
210                          void *res, __u32 reslen)
211 {
212         if (*buflen < reslen) {
213                 CERROR("buflen %u < %u\n", *buflen, reslen);
214                 return -EINVAL;
215         }
216
217         memcpy(res, *buf, reslen);
218         *buf += reslen;
219         *buflen -= reslen;
220         return 0;
221 }