Dont just cast *enum_t to *uint32_t
[deb_libnfs.git] / lib / libnfs-zdr.c
CommitLineData
763cd6e3
RS
1/*
2 Copyright (C) 2012 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
16*/
17/*
18 * This file contains definitions for the built in ZDR implementation.
19 * This is a very limited ZDR subset that can only marshal to/from a momory buffer,
20 * i.e. zdrmem_create() buffers.
21 * It aims to be compatible with normal rpcgen generated functions.
22 */
23
24#include <stdlib.h>
25#include <string.h>
26#include "libnfs-zdr.h"
27
28struct opaque_auth _null_auth;
29
30bool_t libnfs_zdr_setpos(ZDR *zdrs, uint32_t pos)
31{
32 zdrs->pos = pos;
242b81cf
RS
33
34 return TRUE;
763cd6e3
RS
35}
36
37uint32_t libnfs_zdr_getpos(ZDR *zdrs)
38{
39 return zdrs->pos;
40}
41
42void libnfs_zdrmem_create(ZDR *zdrs, const caddr_t addr, uint32_t size, enum zdr_op xop)
43{
44 zdrs->x_op = xop;
45 zdrs->buf = addr;
46 zdrs->size = size;
47 zdrs->pos = 0;
48 zdrs->mem = NULL;
49}
50
51static void *zdr_malloc(ZDR *zdrs, uint32_t size)
52{
53 struct zdr_mem *mem;
54
55 mem = malloc(sizeof(struct zdr_mem));
56 mem->next = zdrs->mem;
57 mem->size = size;
58 mem->buf = malloc(mem->size);
59 zdrs->mem = mem;
60
61 return mem->buf;
62}
63
64void libnfs_zdr_destroy(ZDR *zdrs)
65{
66 while (zdrs->mem != NULL) {
67 struct zdr_mem *mem = zdrs->mem->next;
68 free(zdrs->mem->buf);
69 free(zdrs->mem);
70 zdrs->mem = mem;
71 }
72}
73
74bool_t libnfs_zdr_u_int(ZDR *zdrs, uint32_t *u)
75{
76 if (zdrs->pos + 4 > zdrs->size) {
77 return FALSE;
78 }
79
80 switch (zdrs->x_op) {
81 case ZDR_ENCODE:
82 *(uint32_t *)&zdrs->buf[zdrs->pos] = htonl(*u);
83 zdrs->pos += 4;
84 return TRUE;
85 break;
86 case ZDR_DECODE:
87 *u = ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]);
88 zdrs->pos += 4;
89 return TRUE;
90 break;
91 }
92
93 return FALSE;
94}
95
96bool_t libnfs_zdr_int(ZDR *zdrs, int32_t *i)
97{
98 return libnfs_zdr_u_int(zdrs, (uint32_t *)i);
99}
100
101bool_t libnfs_zdr_u_quad_t(ZDR *zdrs, uint64_t *u)
102{
103 if (zdrs->pos + 8 > zdrs->size) {
104 return FALSE;
105 }
106
107 switch (zdrs->x_op) {
108 case ZDR_ENCODE:
109 *(uint32_t *)&zdrs->buf[zdrs->pos] = htonl((*u >> 32));
110 zdrs->pos += 4;
111 *(uint32_t *)&zdrs->buf[zdrs->pos] = htonl((*u & 0xffffffff));
112 zdrs->pos += 4;
113 return TRUE;
114 break;
115 case ZDR_DECODE:
116 *u = ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]);
117 zdrs->pos += 4;
118 *u <<= 32;
119 *u |= ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]);
120 zdrs->pos += 4;
121 return TRUE;
122 break;
123 }
124
125 return FALSE;
126}
127
128bool_t libnfs_zdr_quad_t(ZDR *zdrs, int64_t *i)
129{
130 return libnfs_zdr_u_quad_t(zdrs, (uint64_t *)i);
131}
132
133bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize)
134{
135 if (!libnfs_zdr_u_int(zdrs, size)) {
136 return FALSE;
137 }
138
139 if (zdrs->pos + *size > zdrs->size) {
140 return FALSE;
141 }
142
143 switch (zdrs->x_op) {
144 case ZDR_ENCODE:
145 memcpy(&zdrs->buf[zdrs->pos], *bufp, *size);
146 zdrs->pos += *size;
147 zdrs->pos = (zdrs->pos + 3) & ~3;
148 return TRUE;
149 case ZDR_DECODE:
150 if (*bufp == NULL) {
151 *bufp = zdr_malloc(zdrs, *size);
152 }
153 memcpy(*bufp, &zdrs->buf[zdrs->pos], *size);
154 zdrs->pos += *size;
155 zdrs->pos = (zdrs->pos + 3) & ~3;
156 return TRUE;
157 }
158
159 return FALSE;
160}
161
162
442b829a 163bool_t libnfs_zdr_enum(ZDR *zdrs, enum_t *e)
763cd6e3 164{
442b829a
RS
165 bool_t ret;
166 int32_t i = *e;
167
168 ret = libnfs_zdr_u_int(zdrs, (uint32_t *)&i);
169 *e = i;
170
171 return ret;
763cd6e3
RS
172}
173
174bool_t libnfs_zdr_bool(ZDR *zdrs, bool_t *b)
175{
176 return libnfs_zdr_u_int(zdrs, (uint32_t *)b);
177}
178
179bool_t libnfs_zdr_void(void)
180{
181 return TRUE;
182}
183
184bool_t libnfs_zdr_pointer(ZDR *zdrs, char **objp, uint32_t size, zdrproc_t proc)
185{
186 bool_t more_data;
187
188 more_data = (*objp != NULL);
189
190 if (!libnfs_zdr_bool(zdrs, &more_data)) {
191 return FALSE;
192 }
193 if (more_data == 0) {
194 *objp = NULL;
195 return TRUE;
196 }
197
198 if (zdrs->x_op == ZDR_DECODE) {
199 *objp = zdr_malloc(zdrs, size);
200 if (*objp == NULL) {
201 return FALSE;
202 }
203 memset(*objp, 0, size);
204 }
205 return proc(zdrs, *objp);
206}
207
208bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size)
209{
210 switch (zdrs->x_op) {
211 case ZDR_ENCODE:
212 memcpy(&zdrs->buf[zdrs->pos], objp, size);
213 zdrs->pos += size;
214 zdrs->pos = (zdrs->pos + 3) & ~3;
215 return TRUE;
216 case ZDR_DECODE:
217 memcpy(objp, &zdrs->buf[zdrs->pos], size);
218 zdrs->pos += size;
219 zdrs->pos = (zdrs->pos + 3) & ~3;
220 return TRUE;
221 }
222
223 return FALSE;
224}
225
226bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize)
227{
228 uint32_t size;
229
230 if (zdrs->x_op == ZDR_ENCODE) {
231 size = strlen(*strp);
232 }
233
234 if (!libnfs_zdr_u_int(zdrs, &size)) {
235 return FALSE;
236 }
237
238 if (zdrs->pos + size > zdrs->size) {
239 return FALSE;
240 }
241
242 switch (zdrs->x_op) {
243 case ZDR_ENCODE:
244 return libnfs_zdr_opaque(zdrs, *strp, size);
245 case ZDR_DECODE:
246 *strp = zdr_malloc(zdrs, size + 1);
247 if (*strp == NULL) {
248 return FALSE;
249 }
250 (*strp)[size] = 0;
251 return libnfs_zdr_opaque(zdrs, *strp, size);
252 }
253
254 return FALSE;
255}
256
257bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize, uint32_t elsize, zdrproc_t proc)
258{
259 int i;
260
261 if (!libnfs_zdr_u_int(zdrs, size)) {
262 return FALSE;
263 }
264
265 if (zdrs->pos + *size * elsize > zdrs->size) {
266 return FALSE;
267 }
268
269 if (zdrs->x_op == ZDR_DECODE) {
270 *arrp = zdr_malloc(zdrs, *size * elsize);
271 if (*arrp == NULL) {
272 return FALSE;
273 }
274 memset(*arrp, 0, *size * elsize);
275 }
276
277 for (i = 0; i < *size; i++) {
278 if (proc(zdrs, *arrp + i * elsize)) {
279 return FALSE;
280 }
281 }
282 return TRUE;
283}
284
285void libnfs_zdr_free(zdrproc_t proc, char *objp)
286{
287}
288
289static bool_t libnfs_opaque_auth(ZDR *zdrs, struct opaque_auth *auth)
290{
291 if (!libnfs_zdr_u_int(zdrs, &auth->oa_flavor)) {
292 return FALSE;
293 }
294
020f1728 295 if (!libnfs_zdr_bytes(zdrs, &auth->oa_base, &auth->oa_length, auth->oa_length)) {
763cd6e3
RS
296 return FALSE;
297 }
298
299 return TRUE;
300}
301
302static bool_t libnfs_rpc_call_body(ZDR *zdrs, struct call_body *cmb)
303{
304 if (!libnfs_zdr_u_int(zdrs, &cmb->cb_rpcvers)) {
305 return FALSE;
306 }
307
308 if (!libnfs_zdr_u_int(zdrs, &cmb->cb_prog)) {
309 return FALSE;
310 }
311
312 if (!libnfs_zdr_u_int(zdrs, &cmb->cb_vers)) {
313 return FALSE;
314 }
315
316 if (!libnfs_zdr_u_int(zdrs, &cmb->cb_proc)) {
317 return FALSE;
318 }
319
320 if (!libnfs_opaque_auth(zdrs, &cmb->cb_cred)) {
321 return FALSE;
322 }
323
324 if (!libnfs_opaque_auth(zdrs, &cmb->cb_verf)) {
325 return FALSE;
326 }
10a0ceaa
RS
327
328 return TRUE;
763cd6e3
RS
329}
330
331static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar)
332{
333 if (!libnfs_opaque_auth(zdrs, &ar->ar_verf)) {
334 return FALSE;
335 }
336
337 if (!libnfs_zdr_u_int(zdrs, &ar->ar_stat)) {
338 return FALSE;
339 }
340
341 switch (ar->ar_stat) {
342 case SUCCESS:
343 if (!ar->ar_results.proc(zdrs, ar->ar_results.where)) {
344 return FALSE;
345 }
346 return TRUE;
347 case PROG_MISMATCH:
348 if (!libnfs_zdr_u_int(zdrs, &ar->ar_vers.low)) {
349 return FALSE;
350 }
351 if (!libnfs_zdr_u_int(zdrs, &ar->ar_vers.high)) {
352 return FALSE;
353 }
354 return TRUE;
355 default:
356 return TRUE;
357 }
358
359 return FALSE;
360}
361
362static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *RP_dr)
363{
364printf("rejected reply\n");
365exit(10);
366}
367
368static bool_t libnfs_rpc_reply_body(ZDR *zdrs, struct reply_body *rmb)
369{
370 if (!libnfs_zdr_u_int(zdrs, &rmb->rp_stat)) {
371 return FALSE;
372 }
373
374 switch (rmb->rp_stat) {
375 case MSG_ACCEPTED:
376 if (!libnfs_accepted_reply(zdrs, &rmb->rp_acpt)) {
377 return FALSE;
378 }
379 return TRUE;
380 case MSG_DENIED:
381 if (!libnfs_rejected_reply(zdrs, &rmb->rp_rjct)) {
382 return FALSE;
383 }
384 return TRUE;
385 }
386
387 return FALSE;
388}
389
390static bool_t libnfs_rpc_msg(ZDR *zdrs, struct rpc_msg *msg)
391{
392 if (!libnfs_zdr_u_int(zdrs, &msg->rm_xid)) {
393 return FALSE;
394 }
395
396 if (!libnfs_zdr_u_int(zdrs, &msg->rm_direction)) {
397 return FALSE;
398 }
399
400 switch (msg->rm_direction) {
401 case CALL:
402 return libnfs_rpc_call_body(zdrs, &msg->ru.RM_cmb);
403 break;
404 case REPLY:
405 return libnfs_rpc_reply_body(zdrs, &msg->ru.RM_rmb);
406 break;
407 default:
408 return FALSE;
409 }
410}
411
412bool_t libnfs_zdr_callmsg(ZDR *zdrs, struct rpc_msg *msg)
413{
414 return libnfs_rpc_msg(zdrs, msg);
415}
416
417bool_t libnfs_zdr_replymsg(ZDR *zdrs, struct rpc_msg *msg)
418{
419 return libnfs_rpc_msg(zdrs, msg);
420}
421
67ba2239 422struct AUTH *authnone_create(void)
763cd6e3 423{
67ba2239 424 struct AUTH *auth;
763cd6e3 425
67ba2239 426 auth = malloc(sizeof(struct AUTH));
763cd6e3
RS
427
428 auth->ah_cred.oa_flavor = AUTH_NONE;
429 auth->ah_cred.oa_length = 0;
430 auth->ah_cred.oa_base = NULL;
431
432 auth->ah_verf.oa_flavor = AUTH_NONE;
433 auth->ah_verf.oa_length = 0;
434 auth->ah_verf.oa_base = NULL;
435
436 auth->ah_private = NULL;
437
438 return auth;
439}
440
67ba2239 441struct AUTH *libnfs_authunix_create(char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups)
763cd6e3 442{
67ba2239 443 struct AUTH *auth;
763cd6e3
RS
444 int size;
445 uint32_t *buf;
446 int idx;
447
448 size = 4 + 4 + ((strlen(host) + 3) & ~3) + 4 + 4 + 4 + len * 4;
67ba2239 449 auth = malloc(sizeof(struct AUTH));
763cd6e3
RS
450 auth->ah_cred.oa_flavor = AUTH_UNIX;
451 auth->ah_cred.oa_length = size;
452 auth->ah_cred.oa_base = malloc(size);
453
45670bd0 454 buf = (uint32_t *)auth->ah_cred.oa_base;
763cd6e3
RS
455 idx = 0;
456 buf[idx++] = htonl(time(NULL));
457 buf[idx++] = htonl(strlen(host));
458 memcpy(&buf[2], host, strlen(host));
459
460 idx += (strlen(host) + 3) >> 2;
461 buf[idx++] = htonl(uid);
462 buf[idx++] = htonl(gid);
463 buf[idx++] = htonl(len);
464 while (len-- > 0) {
465 buf[idx++] = htonl(*groups++);
466 }
467
468 auth->ah_verf.oa_flavor = AUTH_NONE;
469 auth->ah_verf.oa_length = 0;
470 auth->ah_verf.oa_base = NULL;
471
472 auth->ah_private = NULL;
473
474 return auth;
475}
476
67ba2239 477struct AUTH *libnfs_authunix_create_default(void)
763cd6e3
RS
478{
479 return libnfs_authunix_create("libnfs", getuid(), -1, 0, NULL);
480}
481
67ba2239 482void libnfs_auth_destroy(struct AUTH *auth)
763cd6e3
RS
483{
484 if (auth->ah_cred.oa_base) {
485 free(auth->ah_cred.oa_base);
486 }
487 if (auth->ah_verf.oa_base) {
488 free(auth->ah_verf.oa_base);
489 }
490 free(auth);
491}
492