source: branches/samba-3.5.x/librpc/ndr/ndr_basic.c

Last change on this file was 596, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update trunk to 3.5.8

File size: 26.6 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 routines for marshalling/unmarshalling basic types
5
6 Copyright (C) Andrew Tridgell 2003
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 as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23#include "system/network.h"
24#include "librpc/ndr/libndr.h"
25
26#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
27#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
28#define NDR_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))
29#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
30#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
31#define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
32
33
34/*
35 check for data leaks from the server by looking for non-zero pad bytes
36 these could also indicate that real structure elements have been
37 mistaken for padding in the IDL
38*/
39_PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
40{
41 size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1);
42 int i;
43 for (i=ndr->offset;i<ofs2;i++) {
44 if (ndr->data[i] != 0) {
45 break;
46 }
47 }
48 if (i<ofs2) {
49 DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n));
50 for (i=ndr->offset;i<ofs2;i++) {
51 DEBUG(0,("%02x ", ndr->data[i]));
52 }
53 DEBUG(0,("\n"));
54 }
55
56}
57
58/*
59 parse a int8_t
60*/
61_PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
62{
63 NDR_PULL_NEED_BYTES(ndr, 1);
64 *v = (int8_t)CVAL(ndr->data, ndr->offset);
65 ndr->offset += 1;
66 return NDR_ERR_SUCCESS;
67}
68
69/*
70 parse a uint8_t
71*/
72_PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
73{
74 NDR_PULL_NEED_BYTES(ndr, 1);
75 *v = CVAL(ndr->data, ndr->offset);
76 ndr->offset += 1;
77 return NDR_ERR_SUCCESS;
78}
79
80/*
81 parse a int16_t
82*/
83_PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
84{
85 NDR_PULL_ALIGN(ndr, 2);
86 NDR_PULL_NEED_BYTES(ndr, 2);
87 *v = (uint16_t)NDR_SVAL(ndr, ndr->offset);
88 ndr->offset += 2;
89 return NDR_ERR_SUCCESS;
90}
91
92/*
93 parse a uint16_t
94*/
95_PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
96{
97 NDR_PULL_ALIGN(ndr, 2);
98 NDR_PULL_NEED_BYTES(ndr, 2);
99 *v = NDR_SVAL(ndr, ndr->offset);
100 ndr->offset += 2;
101 return NDR_ERR_SUCCESS;
102}
103
104/*
105 parse a uint1632_t
106*/
107_PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
108{
109 if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
110 uint32_t v32 = 0;
111 enum ndr_err_code err = ndr_pull_uint32(ndr, ndr_flags, &v32);
112 *v = v32;
113 if (unlikely(v32 != *v)) {
114 DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
115 return NDR_ERR_NDR64;
116 }
117 return err;
118 }
119 return ndr_pull_uint16(ndr, ndr_flags, v);
120}
121
122/*
123 parse a int32_t
124*/
125_PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
126{
127 NDR_PULL_ALIGN(ndr, 4);
128 NDR_PULL_NEED_BYTES(ndr, 4);
129 *v = NDR_IVALS(ndr, ndr->offset);
130 ndr->offset += 4;
131 return NDR_ERR_SUCCESS;
132}
133
134/*
135 parse a uint32_t
136*/
137_PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
138{
139 NDR_PULL_ALIGN(ndr, 4);
140 NDR_PULL_NEED_BYTES(ndr, 4);
141 *v = NDR_IVAL(ndr, ndr->offset);
142 ndr->offset += 4;
143 return NDR_ERR_SUCCESS;
144}
145
146/*
147 parse a arch dependent uint32/uint64
148*/
149_PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
150{
151 uint64_t v64;
152 enum ndr_err_code err;
153 if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) {
154 return ndr_pull_uint32(ndr, ndr_flags, v);
155 }
156 err = ndr_pull_hyper(ndr, ndr_flags, &v64);
157 *v = (uint32_t)v64;
158 if (unlikely(v64 != *v)) {
159 DEBUG(0,(__location__ ": non-zero upper 32 bits 0x%016llx\n",
160 (unsigned long long)v64));
161 return NDR_ERR_NDR64;
162 }
163 return err;
164}
165
166/*
167 parse a double
168*/
169_PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v)
170{
171 NDR_PULL_ALIGN(ndr, 8);
172 NDR_PULL_NEED_BYTES(ndr, 8);
173 memcpy(v, ndr->data+ndr->offset, 8);
174 ndr->offset += 8;
175 return NDR_ERR_SUCCESS;
176}
177
178/*
179 parse a pointer referent identifier
180*/
181_PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
182{
183 NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
184 if (*v != 0) {
185 ndr->ptr_count++;
186 }
187 return NDR_ERR_SUCCESS;
188}
189
190/*
191 parse a ref pointer referent identifier
192*/
193_PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
194{
195 NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
196 /* ref pointers always point to data */
197 *v = 1;
198 return NDR_ERR_SUCCESS;
199}
200
201/*
202 parse a udlong
203*/
204_PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
205{
206 NDR_PULL_ALIGN(ndr, 4);
207 NDR_PULL_NEED_BYTES(ndr, 8);
208 *v = NDR_IVAL(ndr, ndr->offset);
209 *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
210 ndr->offset += 8;
211 return NDR_ERR_SUCCESS;
212}
213
214/*
215 parse a udlongr
216*/
217_PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
218{
219 NDR_PULL_ALIGN(ndr, 4);
220 NDR_PULL_NEED_BYTES(ndr, 8);
221 *v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32;
222 *v |= NDR_IVAL(ndr, ndr->offset+4);
223 ndr->offset += 8;
224 return NDR_ERR_SUCCESS;
225}
226
227/*
228 parse a dlong
229*/
230_PUBLIC_ enum ndr_err_code ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v)
231{
232 return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v);
233}
234
235/*
236 parse a hyper
237*/
238_PUBLIC_ enum ndr_err_code ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
239{
240 NDR_PULL_ALIGN(ndr, 8);
241 return ndr_pull_udlong(ndr, ndr_flags, v);
242}
243
244/*
245 parse a pointer
246*/
247_PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v)
248{
249 uintptr_t h;
250 NDR_PULL_ALIGN(ndr, sizeof(h));
251 NDR_PULL_NEED_BYTES(ndr, sizeof(h));
252 memcpy(&h, ndr->data+ndr->offset, sizeof(h));
253 ndr->offset += sizeof(h);
254 *v = (void *)h;
255 return NDR_ERR_SUCCESS;
256}
257
258/*
259 pull a NTSTATUS
260*/
261_PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
262{
263 uint32_t v;
264 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
265 *status = NT_STATUS(v);
266 return NDR_ERR_SUCCESS;
267}
268
269/*
270 push a NTSTATUS
271*/
272_PUBLIC_ enum ndr_err_code ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status)
273{
274 return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status));
275}
276
277_PUBLIC_ void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS r)
278{
279 ndr->print(ndr, "%-25s: %s", name, nt_errstr(r));
280}
281
282/*
283 pull a WERROR
284*/
285_PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
286{
287 uint32_t v;
288 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
289 *status = W_ERROR(v);
290 return NDR_ERR_SUCCESS;
291}
292
293
294/*
295 parse a uint8_t enum
296*/
297_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
298{
299 return ndr_pull_uint8(ndr, ndr_flags, v);
300}
301
302/*
303 parse a uint16_t enum
304*/
305_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
306{
307 return ndr_pull_uint16(ndr, ndr_flags, v);
308}
309
310/*
311 parse a uint1632_t enum (uint32_t on NDR64)
312*/
313_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
314{
315 if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
316 uint32_t v32;
317 NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v32));
318 *v = v32;
319 if (v32 != *v) {
320 DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
321 return NDR_ERR_NDR64;
322 }
323 return NDR_ERR_SUCCESS;
324 }
325 return ndr_pull_uint16(ndr, ndr_flags, v);
326}
327
328/*
329 parse a uint32_t enum
330*/
331_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
332{
333 return ndr_pull_uint32(ndr, ndr_flags, v);
334}
335
336/*
337 push a uint8_t enum
338*/
339_PUBLIC_ enum ndr_err_code ndr_push_enum_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
340{
341 return ndr_push_uint8(ndr, ndr_flags, v);
342}
343
344/*
345 push a uint16_t enum
346*/
347_PUBLIC_ enum ndr_err_code ndr_push_enum_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
348{
349 return ndr_push_uint16(ndr, ndr_flags, v);
350}
351
352/*
353 push a uint32_t enum
354*/
355_PUBLIC_ enum ndr_err_code ndr_push_enum_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
356{
357 return ndr_push_uint32(ndr, ndr_flags, v);
358}
359
360/*
361 push a uint1632_t enum
362*/
363_PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
364{
365 if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
366 return ndr_push_uint32(ndr, ndr_flags, v);
367 }
368 return ndr_push_uint16(ndr, ndr_flags, v);
369}
370
371/*
372 push a WERROR
373*/
374_PUBLIC_ enum ndr_err_code ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status)
375{
376 return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status));
377}
378
379_PUBLIC_ void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR r)
380{
381 ndr->print(ndr, "%-25s: %s", name, win_errstr(r));
382}
383
384/*
385 parse a set of bytes
386*/
387_PUBLIC_ enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n)
388{
389 NDR_PULL_NEED_BYTES(ndr, n);
390 memcpy(data, ndr->data + ndr->offset, n);
391 ndr->offset += n;
392 return NDR_ERR_SUCCESS;
393}
394
395/*
396 pull an array of uint8
397*/
398_PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
399{
400 if (!(ndr_flags & NDR_SCALARS)) {
401 return NDR_ERR_SUCCESS;
402 }
403 return ndr_pull_bytes(ndr, data, n);
404}
405
406/*
407 push a int8_t
408*/
409_PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
410{
411 NDR_PUSH_NEED_BYTES(ndr, 1);
412 SCVAL(ndr->data, ndr->offset, (uint8_t)v);
413 ndr->offset += 1;
414 return NDR_ERR_SUCCESS;
415}
416
417/*
418 push a uint8_t
419*/
420_PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
421{
422 NDR_PUSH_NEED_BYTES(ndr, 1);
423 SCVAL(ndr->data, ndr->offset, v);
424 ndr->offset += 1;
425 return NDR_ERR_SUCCESS;
426}
427
428/*
429 push a int16_t
430*/
431_PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
432{
433 NDR_PUSH_ALIGN(ndr, 2);
434 NDR_PUSH_NEED_BYTES(ndr, 2);
435 NDR_SSVAL(ndr, ndr->offset, (uint16_t)v);
436 ndr->offset += 2;
437 return NDR_ERR_SUCCESS;
438}
439
440/*
441 push a uint16_t
442*/
443_PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
444{
445 NDR_PUSH_ALIGN(ndr, 2);
446 NDR_PUSH_NEED_BYTES(ndr, 2);
447 NDR_SSVAL(ndr, ndr->offset, v);
448 ndr->offset += 2;
449 return NDR_ERR_SUCCESS;
450}
451
452/*
453 push a uint1632
454*/
455_PUBLIC_ enum ndr_err_code ndr_push_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
456{
457 if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
458 return ndr_push_uint32(ndr, ndr_flags, v);
459 }
460 return ndr_push_uint16(ndr, ndr_flags, v);
461}
462
463/*
464 push a int32_t
465*/
466_PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
467{
468 NDR_PUSH_ALIGN(ndr, 4);
469 NDR_PUSH_NEED_BYTES(ndr, 4);
470 NDR_SIVALS(ndr, ndr->offset, v);
471 ndr->offset += 4;
472 return NDR_ERR_SUCCESS;
473}
474
475/*
476 push a uint32_t
477*/
478_PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
479{
480 NDR_PUSH_ALIGN(ndr, 4);
481 NDR_PUSH_NEED_BYTES(ndr, 4);
482 NDR_SIVAL(ndr, ndr->offset, v);
483 ndr->offset += 4;
484 return NDR_ERR_SUCCESS;
485}
486
487/*
488 push a uint3264
489*/
490_PUBLIC_ enum ndr_err_code ndr_push_uint3264(struct ndr_push *ndr, int ndr_flags, uint32_t v)
491{
492 if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
493 return ndr_push_hyper(ndr, ndr_flags, v);
494 }
495 return ndr_push_uint32(ndr, ndr_flags, v);
496}
497
498/*
499 push a udlong
500*/
501_PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
502{
503 NDR_PUSH_ALIGN(ndr, 4);
504 NDR_PUSH_NEED_BYTES(ndr, 8);
505 NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
506 NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
507 ndr->offset += 8;
508 return NDR_ERR_SUCCESS;
509}
510
511/*
512 push a udlongr
513*/
514_PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
515{
516 NDR_PUSH_ALIGN(ndr, 4);
517 NDR_PUSH_NEED_BYTES(ndr, 8);
518 NDR_SIVAL(ndr, ndr->offset, (v>>32));
519 NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF));
520 ndr->offset += 8;
521 return NDR_ERR_SUCCESS;
522}
523
524/*
525 push a dlong
526*/
527_PUBLIC_ enum ndr_err_code ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v)
528{
529 return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v);
530}
531
532/*
533 push a hyper
534*/
535_PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v)
536{
537 NDR_PUSH_ALIGN(ndr, 8);
538 return ndr_push_udlong(ndr, NDR_SCALARS, v);
539}
540
541/*
542 push a double
543*/
544_PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v)
545{
546 NDR_PUSH_ALIGN(ndr, 8);
547 NDR_PUSH_NEED_BYTES(ndr, 8);
548 memcpy(ndr->data+ndr->offset, &v, 8);
549 ndr->offset += 8;
550 return NDR_ERR_SUCCESS;
551}
552
553/*
554 push a pointer
555*/
556_PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v)
557{
558 uintptr_t h = (intptr_t)v;
559 NDR_PUSH_ALIGN(ndr, sizeof(h));
560 NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
561 memcpy(ndr->data+ndr->offset, &h, sizeof(h));
562 ndr->offset += sizeof(h);
563 return NDR_ERR_SUCCESS;
564}
565
566_PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
567{
568 /* this is a nasty hack to make pidl work with NDR64 */
569 if (size == 5) {
570 if (ndr->flags & LIBNDR_FLAG_NDR64) {
571 size = 8;
572 } else {
573 size = 4;
574 }
575 } else if (size == 3) {
576 if (ndr->flags & LIBNDR_FLAG_NDR64) {
577 size = 4;
578 } else {
579 size = 2;
580 }
581 }
582 NDR_PUSH_ALIGN(ndr, size);
583 return NDR_ERR_SUCCESS;
584}
585
586_PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size)
587{
588 /* this is a nasty hack to make pidl work with NDR64 */
589 if (size == 5) {
590 if (ndr->flags & LIBNDR_FLAG_NDR64) {
591 size = 8;
592 } else {
593 size = 4;
594 }
595 } else if (size == 3) {
596 if (ndr->flags & LIBNDR_FLAG_NDR64) {
597 size = 4;
598 } else {
599 size = 2;
600 }
601 }
602 NDR_PULL_ALIGN(ndr, size);
603 return NDR_ERR_SUCCESS;
604}
605
606_PUBLIC_ enum ndr_err_code ndr_push_union_align(struct ndr_push *ndr, size_t size)
607{
608 /* MS-RPCE section 2.2.5.3.4.4 */
609 if (ndr->flags & LIBNDR_FLAG_NDR64) {
610 return ndr_push_align(ndr, size);
611 }
612 return NDR_ERR_SUCCESS;
613}
614
615_PUBLIC_ enum ndr_err_code ndr_pull_union_align(struct ndr_pull *ndr, size_t size)
616{
617 /* MS-RPCE section 2.2.5.3.4.4 */
618 if (ndr->flags & LIBNDR_FLAG_NDR64) {
619 return ndr_pull_align(ndr, size);
620 }
621 return NDR_ERR_SUCCESS;
622}
623
624_PUBLIC_ enum ndr_err_code ndr_push_trailer_align(struct ndr_push *ndr, size_t size)
625{
626 /* MS-RPCE section 2.2.5.3.4.1 */
627 if (ndr->flags & LIBNDR_FLAG_NDR64) {
628 return ndr_push_align(ndr, size);
629 }
630 return NDR_ERR_SUCCESS;
631}
632
633_PUBLIC_ enum ndr_err_code ndr_pull_trailer_align(struct ndr_pull *ndr, size_t size)
634{
635 /* MS-RPCE section 2.2.5.3.4.1 */
636 if (ndr->flags & LIBNDR_FLAG_NDR64) {
637 return ndr_pull_align(ndr, size);
638 }
639 return NDR_ERR_SUCCESS;
640}
641
642/*
643 push some bytes
644*/
645_PUBLIC_ enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n)
646{
647 NDR_PUSH_NEED_BYTES(ndr, n);
648 memcpy(ndr->data + ndr->offset, data, n);
649 ndr->offset += n;
650 return NDR_ERR_SUCCESS;
651}
652
653/*
654 push some zero bytes
655*/
656_PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n)
657{
658 NDR_PUSH_NEED_BYTES(ndr, n);
659 memset(ndr->data + ndr->offset, 0, n);
660 ndr->offset += n;
661 return NDR_ERR_SUCCESS;
662}
663
664/*
665 push an array of uint8
666*/
667_PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
668{
669 if (!(ndr_flags & NDR_SCALARS)) {
670 return NDR_ERR_SUCCESS;
671 }
672 return ndr_push_bytes(ndr, data, n);
673}
674
675/*
676 push a unique non-zero value if a pointer is non-NULL, otherwise 0
677*/
678_PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
679{
680 uint32_t ptr = 0;
681 if (p) {
682 ptr = ndr->ptr_count * 4;
683 ptr |= 0x00020000;
684 ndr->ptr_count++;
685 }
686 return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
687}
688
689/*
690 push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0
691*/
692_PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
693{
694 uint32_t ptr = 0;
695 if (p) {
696 /* Check if the pointer already exists and has an id */
697 ptr = ndr_token_peek(&ndr->full_ptr_list, p);
698 if (ptr == 0) {
699 ndr->ptr_count++;
700 ptr = ndr->ptr_count;
701 ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
702 }
703 }
704 return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
705}
706
707/*
708 push always a 0, if a pointer is NULL it's a fatal error
709*/
710_PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
711{
712 return ndr_push_uint3264(ndr, NDR_SCALARS, 0xAEF1AEF1);
713}
714
715
716/*
717 push a NTTIME
718*/
719_PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
720{
721 NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
722 return NDR_ERR_SUCCESS;
723}
724
725/*
726 pull a NTTIME
727*/
728_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
729{
730 NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
731 return NDR_ERR_SUCCESS;
732}
733
734/*
735 push a NTTIME_1sec
736*/
737_PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
738{
739 t /= 10000000;
740 NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
741 return NDR_ERR_SUCCESS;
742}
743
744/*
745 pull a NTTIME_1sec
746*/
747_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
748{
749 NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
750 (*t) *= 10000000;
751 return NDR_ERR_SUCCESS;
752}
753
754/*
755 pull a NTTIME_hyper
756*/
757_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
758{
759 NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
760 return NDR_ERR_SUCCESS;
761}
762
763/*
764 push a NTTIME_hyper
765*/
766_PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
767{
768 NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
769 return NDR_ERR_SUCCESS;
770}
771
772/*
773 push a time_t
774*/
775_PUBLIC_ enum ndr_err_code ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t)
776{
777 return ndr_push_uint32(ndr, ndr_flags, t);
778}
779
780/*
781 pull a time_t
782*/
783_PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t)
784{
785 uint32_t tt;
786 NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt));
787 *t = tt;
788 return NDR_ERR_SUCCESS;
789}
790
791
792/*
793 pull a ipv4address
794*/
795_PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address)
796{
797 uint32_t addr;
798 struct in_addr in;
799 NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &addr));
800 in.s_addr = htonl(addr);
801 *address = talloc_strdup(ndr->current_mem_ctx, inet_ntoa(in));
802 NDR_ERR_HAVE_NO_MEMORY(*address);
803 return NDR_ERR_SUCCESS;
804}
805
806/*
807 push a ipv4address
808*/
809_PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
810{
811 uint32_t addr;
812 if (!is_ipaddress(address)) {
813 return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
814 "Invalid IPv4 address: '%s'",
815 address);
816 }
817 addr = inet_addr(address);
818 NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
819 return NDR_ERR_SUCCESS;
820}
821
822/*
823 print a ipv4address
824*/
825_PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name,
826 const char *address)
827{
828 ndr->print(ndr, "%-25s: %s", name, address);
829}
830
831
832_PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
833{
834 ndr->print(ndr, "%s: struct %s", name, type);
835}
836
837_PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type,
838 const char *val, uint32_t value)
839{
840 if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
841 ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
842 } else {
843 ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
844 }
845}
846
847_PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value)
848{
849 /* this is an attempt to support multi-bit bitmap masks */
850 value &= flag;
851
852 while (!(flag & 1)) {
853 flag >>= 1;
854 value >>= 1;
855 }
856 if (flag == 1) {
857 ndr->print(ndr, " %d: %-25s", value, flag_name);
858 } else {
859 ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
860 }
861}
862
863_PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v)
864{
865 ndr->print(ndr, "%-25s: %d", name, v);
866}
867
868_PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
869{
870 ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
871}
872
873_PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v)
874{
875 ndr->print(ndr, "%-25s: %d", name, v);
876}
877
878_PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
879{
880 ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
881}
882
883_PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
884{
885 ndr->print(ndr, "%-25s: %d", name, v);
886}
887
888_PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
889{
890 ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
891}
892
893_PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
894{
895 ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v);
896}
897
898_PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v)
899{
900 ndr_print_udlong(ndr, name, v);
901}
902
903_PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
904{
905 ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v);
906}
907
908_PUBLIC_ void ndr_print_double(struct ndr_print *ndr, const char *name, double v)
909{
910 ndr->print(ndr, "%-25s: %f", name, v);
911}
912
913_PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
914{
915 ndr_print_dlong(ndr, name, v);
916}
917
918_PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v)
919{
920 ndr->print(ndr, "%-25s: %p", name, v);
921}
922
923_PUBLIC_ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
924{
925 if (p) {
926 ndr->print(ndr, "%-25s: *", name);
927 } else {
928 ndr->print(ndr, "%-25s: NULL", name);
929 }
930}
931
932_PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
933{
934 ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
935}
936
937_PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
938{
939 /* this is a standard NTTIME here
940 * as it's already converted in the pull/push code
941 */
942 ndr_print_NTTIME(ndr, name, t);
943}
944
945_PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
946{
947 ndr_print_NTTIME(ndr, name, t);
948}
949
950_PUBLIC_ void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
951{
952 if (t == (time_t)-1 || t == 0) {
953 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
954 } else {
955 ndr->print(ndr, "%-25s: %s", name, timestring(ndr, t));
956 }
957}
958
959_PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type)
960{
961 if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
962 ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level);
963 } else {
964 ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level);
965 }
966}
967
968_PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
969{
970 ndr->print(ndr, "UNKNOWN LEVEL %u", level);
971}
972
973_PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
974 const uint8_t *data, uint32_t count)
975{
976 int i;
977
978 if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
979 char s[1202];
980 for (i=0;i<count;i++) {
981 snprintf(&s[i*2], 3, "%02x", data[i]);
982 }
983 s[i*2] = 0;
984 ndr->print(ndr, "%-25s: %s", name, s);
985 return;
986 }
987
988 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
989 ndr->depth++;
990 for (i=0;i<count;i++) {
991 char *idx=NULL;
992 if (asprintf(&idx, "[%d]", i) != -1) {
993 ndr_print_uint8(ndr, idx, data[i]);
994 free(idx);
995 }
996 }
997 ndr->depth--;
998}
999
1000_PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
1001{
1002 ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length);
1003 if (r.length) {
1004 dump_data(10, r.data, r.length);
1005 }
1006}
1007
1008
1009/*
1010 push a DATA_BLOB onto the wire.
1011*/
1012_PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
1013{
1014 if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1015 /* nothing to do */
1016 } else if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
1017 if (ndr->flags & LIBNDR_FLAG_NOALIGN) {
1018 blob.length = 0;
1019 } else if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1020 blob.length = NDR_ALIGN(ndr, 2);
1021 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1022 blob.length = NDR_ALIGN(ndr, 4);
1023 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1024 blob.length = NDR_ALIGN(ndr, 8);
1025 }
1026 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
1027 data_blob_clear(&blob);
1028 } else {
1029 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, blob.length));
1030 }
1031 NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
1032 return NDR_ERR_SUCCESS;
1033}
1034
1035/*
1036 pull a DATA_BLOB from the wire.
1037*/
1038_PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
1039{
1040 uint32_t length = 0;
1041
1042 if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1043 length = ndr->data_size - ndr->offset;
1044 } else if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
1045 if (ndr->flags & LIBNDR_FLAG_NOALIGN) {
1046 length = 0;
1047 } else if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1048 length = NDR_ALIGN(ndr, 2);
1049 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1050 length = NDR_ALIGN(ndr, 4);
1051 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1052 length = NDR_ALIGN(ndr, 8);
1053 }
1054 if (ndr->data_size - ndr->offset < length) {
1055 length = ndr->data_size - ndr->offset;
1056 }
1057 } else {
1058 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
1059 }
1060 NDR_PULL_NEED_BYTES(ndr, length);
1061 *blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
1062 ndr->offset += length;
1063 return NDR_ERR_SUCCESS;
1064}
1065
1066_PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
1067{
1068 if (!data) return ret;
1069 return ret + data->length;
1070}
Note: See TracBrowser for help on using the repository browser.