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 "replace.h"
23 #include "system/network.h"
24 #include "librpc/ndr/libndr.h"
25 #include "lib/util/util_net.h"
26 #include "lib/util/debug.h"
27 #include "lib/util/util.h"
28 
29 #define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
30 #define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
31 #define NDR_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))
32 #define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
33 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
34 #define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
35 
36 
37 static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len);
38 
39 /*
40   check for data leaks from the server by looking for non-zero pad bytes
41   these could also indicate that real structure elements have been
42   mistaken for padding in the IDL
43 */
ndr_check_padding(struct ndr_pull * ndr,size_t n)44 _PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
45 {
46 	size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1);
47 	int i;
48 	for (i=ndr->offset;i<ofs2;i++) {
49 		if (ndr->data[i] != 0) {
50 			break;
51 		}
52 	}
53 	if (i<ofs2) {
54 		DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n));
55 		for (i=ndr->offset;i<ofs2;i++) {
56 			DEBUG(0,("%02x ", ndr->data[i]));
57 		}
58 		DEBUG(0,("\n"));
59 	}
60 
61 }
62 
63 /*
64   parse a int8_t
65 */
ndr_pull_int8(struct ndr_pull * ndr,int ndr_flags,int8_t * v)66 _PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
67 {
68 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
69 	NDR_PULL_NEED_BYTES(ndr, 1);
70 	*v = (int8_t)CVAL(ndr->data, ndr->offset);
71 	ndr->offset += 1;
72 	return NDR_ERR_SUCCESS;
73 }
74 
75 /*
76   parse a uint8_t
77 */
ndr_pull_uint8(struct ndr_pull * ndr,int ndr_flags,uint8_t * v)78 _PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
79 {
80 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
81 	NDR_PULL_NEED_BYTES(ndr, 1);
82 	*v = CVAL(ndr->data, ndr->offset);
83 	ndr->offset += 1;
84 	return NDR_ERR_SUCCESS;
85 }
86 
87 /*
88   parse a int16_t
89 */
ndr_pull_int16(struct ndr_pull * ndr,int ndr_flags,int16_t * v)90 _PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
91 {
92 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
93 	NDR_PULL_ALIGN(ndr, 2);
94 	NDR_PULL_NEED_BYTES(ndr, 2);
95 	*v = (uint16_t)NDR_SVAL(ndr, ndr->offset);
96 	ndr->offset += 2;
97 	return NDR_ERR_SUCCESS;
98 }
99 
100 /*
101   parse a uint16_t
102 */
ndr_pull_uint16(struct ndr_pull * ndr,int ndr_flags,uint16_t * v)103 _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
104 {
105 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
106 	NDR_PULL_ALIGN(ndr, 2);
107 	NDR_PULL_NEED_BYTES(ndr, 2);
108 	*v = NDR_SVAL(ndr, ndr->offset);
109 	ndr->offset += 2;
110 	return NDR_ERR_SUCCESS;
111 }
112 
113 /*
114   parse a uint1632_t
115 */
ndr_pull_uint1632(struct ndr_pull * ndr,int ndr_flags,uint16_t * v)116 _PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
117 {
118 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
119 	if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
120 		uint32_t v32 = 0;
121 		enum ndr_err_code err = ndr_pull_uint32(ndr, ndr_flags, &v32);
122 		*v = v32;
123 		if (unlikely(v32 != *v)) {
124 			DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
125 			return NDR_ERR_NDR64;
126 		}
127 		return err;
128 	}
129 	return ndr_pull_uint16(ndr, ndr_flags, v);
130 }
131 
132 /*
133   parse a int32_t
134 */
ndr_pull_int32(struct ndr_pull * ndr,int ndr_flags,int32_t * v)135 _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
136 {
137 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
138 	NDR_PULL_ALIGN(ndr, 4);
139 	NDR_PULL_NEED_BYTES(ndr, 4);
140 	*v = NDR_IVALS(ndr, ndr->offset);
141 	ndr->offset += 4;
142 	return NDR_ERR_SUCCESS;
143 }
144 
145 /*
146   parse a uint32_t
147 */
ndr_pull_uint32(struct ndr_pull * ndr,int ndr_flags,uint32_t * v)148 _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
149 {
150 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
151 	NDR_PULL_ALIGN(ndr, 4);
152 	NDR_PULL_NEED_BYTES(ndr, 4);
153 	*v = NDR_IVAL(ndr, ndr->offset);
154 	ndr->offset += 4;
155 	return NDR_ERR_SUCCESS;
156 }
157 
158 /*
159   parse a arch dependent uint32/uint64
160 */
ndr_pull_uint3264(struct ndr_pull * ndr,int ndr_flags,uint32_t * v)161 _PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
162 {
163 	uint64_t v64 = 0;
164 	enum ndr_err_code err;
165 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
166 	if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) {
167 		return ndr_pull_uint32(ndr, ndr_flags, v);
168 	}
169 	err = ndr_pull_hyper(ndr, ndr_flags, &v64);
170 	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
171 		return err;
172 	}
173 	*v = (uint32_t)v64;
174 	if (unlikely(v64 != *v)) {
175 		DEBUG(0,(__location__ ": non-zero upper 32 bits 0x%016llx\n",
176 			 (unsigned long long)v64));
177 		return ndr_pull_error(ndr, NDR_ERR_NDR64, __location__ ": non-zero upper 32 bits 0x%016llx\n",
178 			 (unsigned long long)v64);
179 	}
180 	return err;
181 }
182 
183 /*
184   parse a double
185 */
ndr_pull_double(struct ndr_pull * ndr,int ndr_flags,double * v)186 _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v)
187 {
188 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
189 	NDR_PULL_ALIGN(ndr, 8);
190 	NDR_PULL_NEED_BYTES(ndr, 8);
191 	memcpy(v, ndr->data+ndr->offset, 8);
192 	ndr->offset += 8;
193 	return NDR_ERR_SUCCESS;
194 }
195 
196 /*
197   parse a pointer referent identifier stored in 2 bytes
198 */
ndr_pull_relative_ptr_short(struct ndr_pull * ndr,uint16_t * v)199 _PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr_short(struct ndr_pull *ndr, uint16_t *v)
200 {
201 	NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, v));
202 	if (*v != 0) {
203 		ndr->ptr_count++;
204 	}
205 	*(v) -= ndr->relative_rap_convert;
206 	return NDR_ERR_SUCCESS;
207 }
208 
209 /*
210   parse a pointer referent identifier
211 */
ndr_pull_generic_ptr(struct ndr_pull * ndr,uint32_t * v)212 _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
213 {
214 	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
215 	if (*v != 0) {
216 		ndr->ptr_count++;
217 	}
218 	return NDR_ERR_SUCCESS;
219 }
220 
221 /*
222   parse a ref pointer referent identifier
223 */
ndr_pull_ref_ptr(struct ndr_pull * ndr,uint32_t * v)224 _PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
225 {
226 	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
227 	/* ref pointers always point to data */
228 	*v = 1;
229 	return NDR_ERR_SUCCESS;
230 }
231 
232 /*
233   parse a udlong
234 */
ndr_pull_udlong(struct ndr_pull * ndr,int ndr_flags,uint64_t * v)235 _PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
236 {
237 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
238 	NDR_PULL_ALIGN(ndr, 4);
239 	NDR_PULL_NEED_BYTES(ndr, 8);
240 	*v = NDR_IVAL(ndr, ndr->offset);
241 	*v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
242 	ndr->offset += 8;
243 	return NDR_ERR_SUCCESS;
244 }
245 
246 /*
247   parse a udlongr
248 */
ndr_pull_udlongr(struct ndr_pull * ndr,int ndr_flags,uint64_t * v)249 _PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
250 {
251 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
252 	NDR_PULL_ALIGN(ndr, 4);
253 	NDR_PULL_NEED_BYTES(ndr, 8);
254 	*v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32;
255 	*v |= NDR_IVAL(ndr, ndr->offset+4);
256 	ndr->offset += 8;
257 	return NDR_ERR_SUCCESS;
258 }
259 
260 /*
261   parse a dlong
262 */
ndr_pull_dlong(struct ndr_pull * ndr,int ndr_flags,int64_t * v)263 _PUBLIC_ enum ndr_err_code ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v)
264 {
265 	return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v);
266 }
267 
268 /*
269   parse a hyper
270 */
ndr_pull_hyper(struct ndr_pull * ndr,int ndr_flags,uint64_t * v)271 _PUBLIC_ enum ndr_err_code ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
272 {
273 	NDR_PULL_ALIGN(ndr, 8);
274 	if (NDR_BE(ndr)) {
275 		return ndr_pull_udlongr(ndr, ndr_flags, v);
276 	}
277 	return ndr_pull_udlong(ndr, ndr_flags, v);
278 }
279 
280 /*
281   parse a pointer
282 */
ndr_pull_pointer(struct ndr_pull * ndr,int ndr_flags,void ** v)283 _PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v)
284 {
285 	uintptr_t h;
286 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
287 	NDR_PULL_ALIGN(ndr, sizeof(h));
288 	NDR_PULL_NEED_BYTES(ndr, sizeof(h));
289 	memcpy(&h, ndr->data+ndr->offset, sizeof(h));
290 	ndr->offset += sizeof(h);
291 	*v = (void *)h;
292 	return NDR_ERR_SUCCESS;
293 }
294 
295 /*
296   pull a NTSTATUS
297 */
ndr_pull_NTSTATUS(struct ndr_pull * ndr,int ndr_flags,NTSTATUS * status)298 _PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
299 {
300 	uint32_t v;
301 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
302 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
303 	*status = NT_STATUS(v);
304 	return NDR_ERR_SUCCESS;
305 }
306 
307 /*
308   push a NTSTATUS
309 */
ndr_push_NTSTATUS(struct ndr_push * ndr,int ndr_flags,NTSTATUS status)310 _PUBLIC_ enum ndr_err_code ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status)
311 {
312 	return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status));
313 }
314 
ndr_print_NTSTATUS(struct ndr_print * ndr,const char * name,NTSTATUS r)315 _PUBLIC_ void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS r)
316 {
317 	ndr->print(ndr, "%-25s: %s", name, nt_errstr(r));
318 }
319 
320 /*
321   pull a WERROR
322 */
ndr_pull_WERROR(struct ndr_pull * ndr,int ndr_flags,WERROR * status)323 _PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
324 {
325 	uint32_t v;
326 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
327 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
328 	*status = W_ERROR(v);
329 	return NDR_ERR_SUCCESS;
330 }
331 
332 /*
333   pull a HRESULT
334 */
ndr_pull_HRESULT(struct ndr_pull * ndr,int ndr_flags,HRESULT * status)335 _PUBLIC_ enum ndr_err_code ndr_pull_HRESULT(struct ndr_pull *ndr, int ndr_flags, HRESULT *status)
336 {
337 	uint32_t v;
338 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
339 	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
340 	*status = HRES_ERROR(v);
341 	return NDR_ERR_SUCCESS;
342 }
343 
344 /*
345   parse a uint8_t enum
346 */
ndr_pull_enum_uint8(struct ndr_pull * ndr,int ndr_flags,uint8_t * v)347 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
348 {
349 	return ndr_pull_uint8(ndr, ndr_flags, v);
350 }
351 
352 /*
353   parse a uint16_t enum
354 */
ndr_pull_enum_uint16(struct ndr_pull * ndr,int ndr_flags,uint16_t * v)355 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
356 {
357 	return ndr_pull_uint16(ndr, ndr_flags, v);
358 }
359 
360 /*
361   parse a uint1632_t enum (uint32_t on NDR64)
362 */
ndr_pull_enum_uint1632(struct ndr_pull * ndr,int ndr_flags,uint16_t * v)363 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
364 {
365 	if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
366 		uint32_t v32;
367 		NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v32));
368 		*v = v32;
369 		if (v32 != *v) {
370 			DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
371 			return NDR_ERR_NDR64;
372 		}
373 		return NDR_ERR_SUCCESS;
374 	}
375 	return ndr_pull_uint16(ndr, ndr_flags, v);
376 }
377 
378 /*
379   parse a uint32_t enum
380 */
ndr_pull_enum_uint32(struct ndr_pull * ndr,int ndr_flags,uint32_t * v)381 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
382 {
383 	return ndr_pull_uint32(ndr, ndr_flags, v);
384 }
385 
386 /*
387   push a uint8_t enum
388 */
ndr_push_enum_uint8(struct ndr_push * ndr,int ndr_flags,uint8_t v)389 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
390 {
391 	return ndr_push_uint8(ndr, ndr_flags, v);
392 }
393 
394 /*
395   push a uint16_t enum
396 */
ndr_push_enum_uint16(struct ndr_push * ndr,int ndr_flags,uint16_t v)397 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
398 {
399 	return ndr_push_uint16(ndr, ndr_flags, v);
400 }
401 
402 /*
403   push a uint32_t enum
404 */
ndr_push_enum_uint32(struct ndr_push * ndr,int ndr_flags,uint32_t v)405 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
406 {
407 	return ndr_push_uint32(ndr, ndr_flags, v);
408 }
409 
410 /*
411   push a uint1632_t enum
412 */
ndr_push_enum_uint1632(struct ndr_push * ndr,int ndr_flags,uint16_t v)413 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
414 {
415 	if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
416 		return ndr_push_uint32(ndr, ndr_flags, v);
417 	}
418 	return ndr_push_uint16(ndr, ndr_flags, v);
419 }
420 
421 /*
422   push a WERROR
423 */
ndr_push_WERROR(struct ndr_push * ndr,int ndr_flags,WERROR status)424 _PUBLIC_ enum ndr_err_code ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status)
425 {
426 	return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status));
427 }
428 
ndr_print_WERROR(struct ndr_print * ndr,const char * name,WERROR r)429 _PUBLIC_ void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR r)
430 {
431 	ndr->print(ndr, "%-25s: %s", name, win_errstr(r));
432 }
433 
434 /*
435   push a HRESULT
436 */
ndr_push_HRESULT(struct ndr_push * ndr,int ndr_flags,HRESULT status)437 _PUBLIC_ enum ndr_err_code ndr_push_HRESULT(struct ndr_push *ndr, int ndr_flags, HRESULT status)
438 {
439 	return ndr_push_uint32(ndr, NDR_SCALARS, HRES_ERROR_V(status));
440 }
441 
ndr_print_HRESULT(struct ndr_print * ndr,const char * name,HRESULT r)442 _PUBLIC_ void ndr_print_HRESULT(struct ndr_print *ndr, const char *name, HRESULT r)
443 {
444 	ndr->print(ndr, "%-25s: %s", name, hresult_errstr(r));
445 }
446 
447 
448 /*
449   parse a set of bytes
450 */
ndr_pull_bytes(struct ndr_pull * ndr,uint8_t * data,uint32_t n)451 _PUBLIC_ enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n)
452 {
453 	NDR_PULL_NEED_BYTES(ndr, n);
454 	memcpy(data, ndr->data + ndr->offset, n);
455 	ndr->offset += n;
456 	return NDR_ERR_SUCCESS;
457 }
458 
459 /*
460   pull an array of uint8
461 */
ndr_pull_array_uint8(struct ndr_pull * ndr,int ndr_flags,uint8_t * data,uint32_t n)462 _PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
463 {
464 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
465 	if (!(ndr_flags & NDR_SCALARS)) {
466 		return NDR_ERR_SUCCESS;
467 	}
468 	return ndr_pull_bytes(ndr, data, n);
469 }
470 
471 /*
472   push a int8_t
473 */
ndr_push_int8(struct ndr_push * ndr,int ndr_flags,int8_t v)474 _PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
475 {
476 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
477 	NDR_PUSH_NEED_BYTES(ndr, 1);
478 	SCVAL(ndr->data, ndr->offset, (uint8_t)v);
479 	ndr->offset += 1;
480 	return NDR_ERR_SUCCESS;
481 }
482 
483 /*
484   push a uint8_t
485 */
ndr_push_uint8(struct ndr_push * ndr,int ndr_flags,uint8_t v)486 _PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
487 {
488 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
489 	NDR_PUSH_NEED_BYTES(ndr, 1);
490 	SCVAL(ndr->data, ndr->offset, v);
491 	ndr->offset += 1;
492 	return NDR_ERR_SUCCESS;
493 }
494 
495 /*
496   push a int16_t
497 */
ndr_push_int16(struct ndr_push * ndr,int ndr_flags,int16_t v)498 _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
499 {
500 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
501 	NDR_PUSH_ALIGN(ndr, 2);
502 	NDR_PUSH_NEED_BYTES(ndr, 2);
503 	NDR_SSVAL(ndr, ndr->offset, (uint16_t)v);
504 	ndr->offset += 2;
505 	return NDR_ERR_SUCCESS;
506 }
507 
508 /*
509   push a uint16_t
510 */
ndr_push_uint16(struct ndr_push * ndr,int ndr_flags,uint16_t v)511 _PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
512 {
513 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
514 	NDR_PUSH_ALIGN(ndr, 2);
515 	NDR_PUSH_NEED_BYTES(ndr, 2);
516 	NDR_SSVAL(ndr, ndr->offset, v);
517 	ndr->offset += 2;
518 	return NDR_ERR_SUCCESS;
519 }
520 
521 /*
522   push a uint1632
523 */
ndr_push_uint1632(struct ndr_push * ndr,int ndr_flags,uint16_t v)524 _PUBLIC_ enum ndr_err_code ndr_push_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
525 {
526 	if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
527 		return ndr_push_uint32(ndr, ndr_flags, v);
528 	}
529 	return ndr_push_uint16(ndr, ndr_flags, v);
530 }
531 
532 /*
533   push a int32_t
534 */
ndr_push_int32(struct ndr_push * ndr,int ndr_flags,int32_t v)535 _PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
536 {
537 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
538 	NDR_PUSH_ALIGN(ndr, 4);
539 	NDR_PUSH_NEED_BYTES(ndr, 4);
540 	NDR_SIVALS(ndr, ndr->offset, v);
541 	ndr->offset += 4;
542 	return NDR_ERR_SUCCESS;
543 }
544 
545 /*
546   push a uint32_t
547 */
ndr_push_uint32(struct ndr_push * ndr,int ndr_flags,uint32_t v)548 _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
549 {
550 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
551 	NDR_PUSH_ALIGN(ndr, 4);
552 	NDR_PUSH_NEED_BYTES(ndr, 4);
553 	NDR_SIVAL(ndr, ndr->offset, v);
554 	ndr->offset += 4;
555 	return NDR_ERR_SUCCESS;
556 }
557 
558 /*
559   push a uint3264
560 */
ndr_push_uint3264(struct ndr_push * ndr,int ndr_flags,uint32_t v)561 _PUBLIC_ enum ndr_err_code ndr_push_uint3264(struct ndr_push *ndr, int ndr_flags, uint32_t v)
562 {
563 	if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
564 		return ndr_push_hyper(ndr, ndr_flags, v);
565 	}
566 	return ndr_push_uint32(ndr, ndr_flags, v);
567 }
568 
569 /*
570   push a udlong
571 */
ndr_push_udlong(struct ndr_push * ndr,int ndr_flags,uint64_t v)572 _PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
573 {
574 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
575 	NDR_PUSH_ALIGN(ndr, 4);
576 	NDR_PUSH_NEED_BYTES(ndr, 8);
577 	NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
578 	NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
579 	ndr->offset += 8;
580 	return NDR_ERR_SUCCESS;
581 }
582 
583 /*
584   push a udlongr
585 */
ndr_push_udlongr(struct ndr_push * ndr,int ndr_flags,uint64_t v)586 _PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
587 {
588 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
589 	NDR_PUSH_ALIGN(ndr, 4);
590 	NDR_PUSH_NEED_BYTES(ndr, 8);
591 	NDR_SIVAL(ndr, ndr->offset, (v>>32));
592 	NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF));
593 	ndr->offset += 8;
594 	return NDR_ERR_SUCCESS;
595 }
596 
597 /*
598   push a dlong
599 */
ndr_push_dlong(struct ndr_push * ndr,int ndr_flags,int64_t v)600 _PUBLIC_ enum ndr_err_code ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v)
601 {
602 	return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v);
603 }
604 
605 /*
606   push a hyper
607 */
ndr_push_hyper(struct ndr_push * ndr,int ndr_flags,uint64_t v)608 _PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v)
609 {
610 	NDR_PUSH_ALIGN(ndr, 8);
611 	if (NDR_BE(ndr)) {
612 		return ndr_push_udlongr(ndr, NDR_SCALARS, v);
613 	}
614 	return ndr_push_udlong(ndr, NDR_SCALARS, v);
615 }
616 
617 /*
618   push a double
619 */
ndr_push_double(struct ndr_push * ndr,int ndr_flags,double v)620 _PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v)
621 {
622 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
623 	NDR_PUSH_ALIGN(ndr, 8);
624 	NDR_PUSH_NEED_BYTES(ndr, 8);
625 	memcpy(ndr->data+ndr->offset, &v, 8);
626 	ndr->offset += 8;
627 	return NDR_ERR_SUCCESS;
628 }
629 
630 /*
631   push a pointer
632 */
ndr_push_pointer(struct ndr_push * ndr,int ndr_flags,void * v)633 _PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v)
634 {
635 	uintptr_t h = (intptr_t)v;
636 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
637 	NDR_PUSH_ALIGN(ndr, sizeof(h));
638 	NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
639 	memcpy(ndr->data+ndr->offset, &h, sizeof(h));
640 	ndr->offset += sizeof(h);
641 	return NDR_ERR_SUCCESS;
642 }
643 
ndr_push_align(struct ndr_push * ndr,size_t size)644 _PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
645 {
646 	/* this is a nasty hack to make pidl work with NDR64 */
647 	if (size == 5) {
648 		if (ndr->flags & LIBNDR_FLAG_NDR64) {
649 			size = 8;
650 		} else {
651 			size = 4;
652 		}
653 	} else if (size == 3) {
654 		if (ndr->flags & LIBNDR_FLAG_NDR64) {
655 			size = 4;
656 		} else {
657 			size = 2;
658 		}
659 	}
660 	NDR_PUSH_ALIGN(ndr, size);
661 	return NDR_ERR_SUCCESS;
662 }
663 
ndr_pull_align(struct ndr_pull * ndr,size_t size)664 _PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size)
665 {
666 	/* this is a nasty hack to make pidl work with NDR64 */
667 	if (size == 5) {
668 		if (ndr->flags & LIBNDR_FLAG_NDR64) {
669 			size = 8;
670 		} else {
671 			size = 4;
672 		}
673 	} else if (size == 3) {
674 		if (ndr->flags & LIBNDR_FLAG_NDR64) {
675 			size = 4;
676 		} else {
677 			size = 2;
678 		}
679 	}
680 	NDR_PULL_ALIGN(ndr, size);
681 	return NDR_ERR_SUCCESS;
682 }
683 
ndr_push_union_align(struct ndr_push * ndr,size_t size)684 _PUBLIC_ enum ndr_err_code ndr_push_union_align(struct ndr_push *ndr, size_t size)
685 {
686 	/* MS-RPCE section 2.2.5.3.4.4 */
687 	if (ndr->flags & LIBNDR_FLAG_NDR64) {
688 		return ndr_push_align(ndr, size);
689 	}
690 	return NDR_ERR_SUCCESS;
691 }
692 
ndr_pull_union_align(struct ndr_pull * ndr,size_t size)693 _PUBLIC_ enum ndr_err_code ndr_pull_union_align(struct ndr_pull *ndr, size_t size)
694 {
695 	/* MS-RPCE section 2.2.5.3.4.4 */
696 	if (ndr->flags & LIBNDR_FLAG_NDR64) {
697 		return ndr_pull_align(ndr, size);
698 	}
699 	return NDR_ERR_SUCCESS;
700 }
701 
ndr_push_trailer_align(struct ndr_push * ndr,size_t size)702 _PUBLIC_ enum ndr_err_code ndr_push_trailer_align(struct ndr_push *ndr, size_t size)
703 {
704 	/* MS-RPCE section 2.2.5.3.4.1 */
705 	if (ndr->flags & LIBNDR_FLAG_NDR64) {
706 		return ndr_push_align(ndr, size);
707 	}
708 	return NDR_ERR_SUCCESS;
709 }
710 
ndr_pull_trailer_align(struct ndr_pull * ndr,size_t size)711 _PUBLIC_ enum ndr_err_code ndr_pull_trailer_align(struct ndr_pull *ndr, size_t size)
712 {
713 	/* MS-RPCE section 2.2.5.3.4.1 */
714 	if (ndr->flags & LIBNDR_FLAG_NDR64) {
715 		return ndr_pull_align(ndr, size);
716 	}
717 	return NDR_ERR_SUCCESS;
718 }
719 
720 /*
721   push some bytes
722 */
ndr_push_bytes(struct ndr_push * ndr,const uint8_t * data,uint32_t n)723 _PUBLIC_ enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n)
724 {
725 	if (unlikely(n == 0)) {
726 		return NDR_ERR_SUCCESS;
727 	}
728 	if (unlikely(data == NULL)) {
729 		return NDR_ERR_INVALID_POINTER;
730 	}
731 	NDR_PUSH_NEED_BYTES(ndr, n);
732 	memcpy(ndr->data + ndr->offset, data, n);
733 	ndr->offset += n;
734 	return NDR_ERR_SUCCESS;
735 }
736 
737 /*
738   push some zero bytes
739 */
ndr_push_zero(struct ndr_push * ndr,uint32_t n)740 _PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n)
741 {
742 	NDR_PUSH_NEED_BYTES(ndr, n);
743 	memset(ndr->data + ndr->offset, 0, n);
744 	ndr->offset += n;
745 	return NDR_ERR_SUCCESS;
746 }
747 
748 /*
749   push an array of uint8
750 */
ndr_push_array_uint8(struct ndr_push * ndr,int ndr_flags,const uint8_t * data,uint32_t n)751 _PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
752 {
753 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
754 	if (!(ndr_flags & NDR_SCALARS)) {
755 		return NDR_ERR_SUCCESS;
756 	}
757 	return ndr_push_bytes(ndr, data, n);
758 }
759 
760 /*
761   push a unique non-zero value if a pointer is non-NULL, otherwise 0
762 */
ndr_push_unique_ptr(struct ndr_push * ndr,const void * p)763 _PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
764 {
765 	uint32_t ptr = 0;
766 	if (p) {
767 		ptr = ndr->ptr_count * 4;
768 		ptr |= 0x00020000;
769 		ndr->ptr_count++;
770 	}
771 	return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
772 }
773 
774 /*
775   push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0
776 */
ndr_push_full_ptr(struct ndr_push * ndr,const void * p)777 _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
778 {
779 	uint32_t ptr = 0;
780 	if (p) {
781 		/* Check if the pointer already exists and has an id */
782 		ptr = ndr_token_peek(&ndr->full_ptr_list, p);
783 		if (ptr == 0) {
784 			enum ndr_err_code ret = NDR_ERR_SUCCESS;
785 			ndr->ptr_count++;
786 			ptr = ndr->ptr_count;
787 			ret = ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
788 			if (ret != NDR_ERR_SUCCESS) {
789 				return ret;
790 			}
791 		}
792 	}
793 	return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
794 }
795 
796 /*
797   push always a 0, if a pointer is NULL it's a fatal error
798 */
ndr_push_ref_ptr(struct ndr_push * ndr)799 _PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
800 {
801 	return ndr_push_uint3264(ndr, NDR_SCALARS, 0xAEF1AEF1);
802 }
803 
804 
805 /*
806   push a NTTIME
807 */
ndr_push_NTTIME(struct ndr_push * ndr,int ndr_flags,NTTIME t)808 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
809 {
810 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
811 	NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
812 	return NDR_ERR_SUCCESS;
813 }
814 
815 /*
816   pull a NTTIME
817 */
ndr_pull_NTTIME(struct ndr_pull * ndr,int ndr_flags,NTTIME * t)818 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
819 {
820 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
821 	NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
822 	return NDR_ERR_SUCCESS;
823 }
824 
825 /*
826   push a NTTIME_1sec
827 */
ndr_push_NTTIME_1sec(struct ndr_push * ndr,int ndr_flags,NTTIME t)828 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
829 {
830 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
831 	t /= 10000000;
832 	NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
833 	return NDR_ERR_SUCCESS;
834 }
835 
836 /*
837   pull a NTTIME_1sec
838 */
ndr_pull_NTTIME_1sec(struct ndr_pull * ndr,int ndr_flags,NTTIME * t)839 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
840 {
841 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
842 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
843 	(*t) *= 10000000;
844 	return NDR_ERR_SUCCESS;
845 }
846 
847 /*
848   pull a NTTIME_hyper
849 */
ndr_pull_NTTIME_hyper(struct ndr_pull * ndr,int ndr_flags,NTTIME * t)850 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
851 {
852 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
853 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
854 	return NDR_ERR_SUCCESS;
855 }
856 
857 /*
858   push a NTTIME_hyper
859 */
ndr_push_NTTIME_hyper(struct ndr_push * ndr,int ndr_flags,NTTIME t)860 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
861 {
862 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
863 	NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
864 	return NDR_ERR_SUCCESS;
865 }
866 
867 /*
868   push a time_t
869 */
ndr_push_time_t(struct ndr_push * ndr,int ndr_flags,time_t t)870 _PUBLIC_ enum ndr_err_code ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t)
871 {
872 	return ndr_push_uint32(ndr, ndr_flags, t);
873 }
874 
875 /*
876   pull a time_t
877 */
ndr_pull_time_t(struct ndr_pull * ndr,int ndr_flags,time_t * t)878 _PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t)
879 {
880 	uint32_t tt;
881 	NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt));
882 	*t = tt;
883 	return NDR_ERR_SUCCESS;
884 }
885 
886 
887 /*
888   push a uid_t
889 */
ndr_push_uid_t(struct ndr_push * ndr,int ndr_flags,uid_t u)890 _PUBLIC_ enum ndr_err_code ndr_push_uid_t(struct ndr_push *ndr, int ndr_flags, uid_t u)
891 {
892 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
893 	return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)u);
894 }
895 
896 /*
897   pull a uid_t
898 */
ndr_pull_uid_t(struct ndr_pull * ndr,int ndr_flags,uid_t * u)899 _PUBLIC_ enum ndr_err_code ndr_pull_uid_t(struct ndr_pull *ndr, int ndr_flags, uid_t *u)
900 {
901 	uint64_t uu = 0;
902 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &uu));
903 	*u = (uid_t)uu;
904 	if (unlikely(uu != *u)) {
905 		DEBUG(0,(__location__ ": uid_t pull doesn't fit 0x%016llx\n",
906 			 (unsigned long long)uu));
907 		return NDR_ERR_NDR64;
908 	}
909 	return NDR_ERR_SUCCESS;
910 }
911 
912 
913 /*
914   push a gid_t
915 */
ndr_push_gid_t(struct ndr_push * ndr,int ndr_flags,gid_t g)916 _PUBLIC_ enum ndr_err_code ndr_push_gid_t(struct ndr_push *ndr, int ndr_flags, gid_t g)
917 {
918 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
919 	return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)g);
920 }
921 
922 /*
923   pull a gid_t
924 */
ndr_pull_gid_t(struct ndr_pull * ndr,int ndr_flags,gid_t * g)925 _PUBLIC_ enum ndr_err_code ndr_pull_gid_t(struct ndr_pull *ndr, int ndr_flags, gid_t *g)
926 {
927 	uint64_t gg = 0;
928 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &gg));
929 	*g = (gid_t)gg;
930 	if (unlikely(gg != *g)) {
931 		DEBUG(0,(__location__ ": gid_t pull doesn't fit 0x%016llx\n",
932 			 (unsigned long long)gg));
933 		return NDR_ERR_NDR64;
934 	}
935 	return NDR_ERR_SUCCESS;
936 }
937 
938 
939 /*
940   pull a ipv4address
941 */
ndr_pull_ipv4address(struct ndr_pull * ndr,int ndr_flags,const char ** address)942 _PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address)
943 {
944 	uint32_t addr;
945 	struct in_addr in;
946 	NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &addr));
947 	in.s_addr = htonl(addr);
948 	*address = talloc_strdup(ndr->current_mem_ctx, inet_ntoa(in));
949 	NDR_ERR_HAVE_NO_MEMORY(*address);
950 	return NDR_ERR_SUCCESS;
951 }
952 
953 /*
954   push a ipv4address
955 */
ndr_push_ipv4address(struct ndr_push * ndr,int ndr_flags,const char * address)956 _PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
957 {
958 	uint32_t addr;
959 	if (!is_ipaddress(address)) {
960 		return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
961 				      "Invalid IPv4 address: '%s'",
962 				      address);
963 	}
964 	addr = inet_addr(address);
965 	NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
966 	return NDR_ERR_SUCCESS;
967 }
968 
969 /*
970   print a ipv4address
971 */
ndr_print_ipv4address(struct ndr_print * ndr,const char * name,const char * address)972 _PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name,
973 			   const char *address)
974 {
975 	ndr->print(ndr, "%-25s: %s", name, address);
976 }
977 
978 /*
979   pull a ipv6address
980 */
981 #define IPV6_BYTES 16
982 #define IPV6_ADDR_STR_LEN 39
ndr_pull_ipv6address(struct ndr_pull * ndr,int ndr_flags,const char ** address)983 _PUBLIC_ enum ndr_err_code ndr_pull_ipv6address(struct ndr_pull *ndr, int ndr_flags, const char **address)
984 {
985 	uint8_t addr[IPV6_BYTES];
986 	char *addr_str = talloc_strdup(ndr->current_mem_ctx, "");
987 	int i;
988 	NDR_CHECK(ndr_pull_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));
989 	for (i = 0; i < IPV6_BYTES; ++i) {
990 		addr_str = talloc_asprintf_append(addr_str, "%02x", addr[i]);
991 		/* We need a ':' every second byte but the last one */
992 		if (i%2 == 1 && i != (IPV6_BYTES - 1)) {
993 			addr_str = talloc_strdup_append(addr_str, ":");
994 		}
995 	}
996 	*address = addr_str;
997 	NDR_ERR_HAVE_NO_MEMORY(*address);
998 	return NDR_ERR_SUCCESS;
999 }
1000 
1001 /*
1002   push a ipv6address
1003 */
ndr_push_ipv6address(struct ndr_push * ndr,int ndr_flags,const char * address)1004 _PUBLIC_ enum ndr_err_code ndr_push_ipv6address(struct ndr_push *ndr, int ndr_flags, const char *address)
1005 {
1006 #ifdef AF_INET6
1007 	uint8_t addr[IPV6_BYTES];
1008 	int ret;
1009 
1010 	if (!is_ipaddress(address)) {
1011 		return ndr_push_error(ndr, NDR_ERR_IPV6ADDRESS,
1012 				      "Invalid IPv6 address: '%s'",
1013 				      address);
1014 	}
1015 	ret = inet_pton(AF_INET6, address, addr);
1016 	if (ret <= 0) {
1017 		return NDR_ERR_IPV6ADDRESS;
1018 	}
1019 
1020 	NDR_CHECK(ndr_push_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));
1021 
1022 	return NDR_ERR_SUCCESS;
1023 #else
1024 	return NDR_ERR_IPV6ADDRESS;
1025 #endif
1026 }
1027 
1028 /*
1029   print a ipv6address
1030 */
ndr_print_ipv6address(struct ndr_print * ndr,const char * name,const char * address)1031 _PUBLIC_ void ndr_print_ipv6address(struct ndr_print *ndr, const char *name,
1032 			   const char *address)
1033 {
1034 	ndr->print(ndr, "%-25s: %s", name, address);
1035 }
1036 #undef IPV6_BYTES
1037 
ndr_print_struct(struct ndr_print * ndr,const char * name,const char * type)1038 _PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
1039 {
1040 	ndr->print(ndr, "%s: struct %s", name, type);
1041 }
1042 
ndr_print_null(struct ndr_print * ndr)1043 _PUBLIC_ void ndr_print_null(struct ndr_print *ndr)
1044 {
1045 	ndr->print(ndr, "UNEXPECTED NULL POINTER");
1046 }
1047 
ndr_print_enum(struct ndr_print * ndr,const char * name,const char * type,const char * val,uint32_t value)1048 _PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type,
1049 		    const char *val, uint32_t value)
1050 {
1051 	if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
1052 		ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
1053 	} else {
1054 		ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
1055 	}
1056 }
1057 
ndr_print_bitmap_flag(struct ndr_print * ndr,size_t size,const char * flag_name,uint32_t flag,uint32_t value)1058 _PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value)
1059 {
1060 	if (flag == 0) {
1061 		return;
1062 	}
1063 
1064 	/* this is an attempt to support multi-bit bitmap masks */
1065 	value &= flag;
1066 
1067 	while (!(flag & 1)) {
1068 		flag >>= 1;
1069 		value >>= 1;
1070 	}
1071 	if (flag == 1) {
1072 		ndr->print(ndr, "   %d: %-25s", value, flag_name);
1073 	} else {
1074 		ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
1075 	}
1076 }
1077 
ndr_print_int8(struct ndr_print * ndr,const char * name,int8_t v)1078 _PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v)
1079 {
1080 	if (NDR_HIDE_SECRET(ndr)) {
1081 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1082 		return;
1083 	}
1084 	ndr->print(ndr, "%-25s: %d", name, v);
1085 }
1086 
ndr_print_uint8(struct ndr_print * ndr,const char * name,uint8_t v)1087 _PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
1088 {
1089 	if (NDR_HIDE_SECRET(ndr)) {
1090 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1091 		return;
1092 	}
1093 	ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
1094 }
1095 
ndr_print_int16(struct ndr_print * ndr,const char * name,int16_t v)1096 _PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v)
1097 {
1098 	if (NDR_HIDE_SECRET(ndr)) {
1099 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1100 		return;
1101 	}
1102 	ndr->print(ndr, "%-25s: %d", name, v);
1103 }
1104 
ndr_print_uint16(struct ndr_print * ndr,const char * name,uint16_t v)1105 _PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
1106 {
1107 	if (NDR_HIDE_SECRET(ndr)) {
1108 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1109 		return;
1110 	}
1111 	ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
1112 }
1113 
ndr_print_int32(struct ndr_print * ndr,const char * name,int32_t v)1114 _PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
1115 {
1116 	if (NDR_HIDE_SECRET(ndr)) {
1117 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1118 		return;
1119 	}
1120 	ndr->print(ndr, "%-25s: %d", name, v);
1121 }
1122 
ndr_print_uint32(struct ndr_print * ndr,const char * name,uint32_t v)1123 _PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
1124 {
1125 	if (NDR_HIDE_SECRET(ndr)) {
1126 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1127 		return;
1128 	}
1129 	ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
1130 }
1131 
ndr_print_int3264(struct ndr_print * ndr,const char * name,int32_t v)1132 _PUBLIC_ void ndr_print_int3264(struct ndr_print *ndr, const char *name, int32_t v)
1133 {
1134 	if (NDR_HIDE_SECRET(ndr)) {
1135 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1136 		return;
1137 	}
1138 	ndr->print(ndr, "%-25s: %d", name, v);
1139 }
1140 
ndr_print_uint3264(struct ndr_print * ndr,const char * name,uint32_t v)1141 _PUBLIC_ void ndr_print_uint3264(struct ndr_print *ndr, const char *name, uint32_t v)
1142 {
1143 	if (NDR_HIDE_SECRET(ndr)) {
1144 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1145 		return;
1146 	}
1147 	ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
1148 }
1149 
ndr_print_udlong(struct ndr_print * ndr,const char * name,uint64_t v)1150 _PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
1151 {
1152 	ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v);
1153 }
1154 
ndr_print_udlongr(struct ndr_print * ndr,const char * name,uint64_t v)1155 _PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v)
1156 {
1157 	ndr_print_udlong(ndr, name, v);
1158 }
1159 
ndr_print_dlong(struct ndr_print * ndr,const char * name,int64_t v)1160 _PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
1161 {
1162 	if (NDR_HIDE_SECRET(ndr)) {
1163 		ndr->print(ndr, "%-25s: <REDACTED SECRET VALUE>", name);
1164 		return;
1165 	}
1166 	ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v);
1167 }
1168 
ndr_print_double(struct ndr_print * ndr,const char * name,double v)1169 _PUBLIC_ void ndr_print_double(struct ndr_print *ndr, const char *name, double v)
1170 {
1171 	ndr->print(ndr, "%-25s: %f", name, v);
1172 }
1173 
ndr_print_hyper(struct ndr_print * ndr,const char * name,uint64_t v)1174 _PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
1175 {
1176 	ndr_print_dlong(ndr, name, v);
1177 }
1178 
ndr_print_pointer(struct ndr_print * ndr,const char * name,void * v)1179 _PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v)
1180 {
1181 	ndr->print(ndr, "%-25s: %p", name, v);
1182 }
1183 
ndr_print_ptr(struct ndr_print * ndr,const char * name,const void * p)1184 _PUBLIC_ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
1185 {
1186 	if (p) {
1187 		ndr->print(ndr, "%-25s: *", name);
1188 	} else {
1189 		ndr->print(ndr, "%-25s: NULL", name);
1190 	}
1191 }
1192 
ndr_print_NTTIME(struct ndr_print * ndr,const char * name,NTTIME t)1193 _PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
1194 {
1195 	ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
1196 }
1197 
ndr_print_NTTIME_1sec(struct ndr_print * ndr,const char * name,NTTIME t)1198 _PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
1199 {
1200 	/* this is a standard NTTIME here
1201 	 * as it's already converted in the pull/push code
1202 	 */
1203 	ndr_print_NTTIME(ndr, name, t);
1204 }
1205 
ndr_print_NTTIME_hyper(struct ndr_print * ndr,const char * name,NTTIME t)1206 _PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
1207 {
1208 	ndr_print_NTTIME(ndr, name, t);
1209 }
1210 
ndr_print_time_t(struct ndr_print * ndr,const char * name,time_t t)1211 _PUBLIC_ void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
1212 {
1213 	if (t == (time_t)-1 || t == 0) {
1214 		ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
1215 	} else {
1216 		ndr->print(ndr, "%-25s: %s", name, timestring(ndr, t));
1217 	}
1218 }
1219 
ndr_print_uid_t(struct ndr_print * ndr,const char * name,uid_t u)1220 _PUBLIC_ void ndr_print_uid_t(struct ndr_print *ndr, const char *name, uid_t u)
1221 {
1222 	ndr_print_dlong(ndr, name, u);
1223 }
1224 
ndr_print_gid_t(struct ndr_print * ndr,const char * name,gid_t g)1225 _PUBLIC_ void ndr_print_gid_t(struct ndr_print *ndr, const char *name, gid_t g)
1226 {
1227 	ndr_print_dlong(ndr, name, g);
1228 }
1229 
ndr_print_union(struct ndr_print * ndr,const char * name,int level,const char * type)1230 _PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type)
1231 {
1232 	if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
1233 		ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level);
1234 	} else {
1235 		ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level);
1236 	}
1237 }
1238 
ndr_print_bad_level(struct ndr_print * ndr,const char * name,uint16_t level)1239 _PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
1240 {
1241 	ndr->print(ndr, "UNKNOWN LEVEL %u", level);
1242 }
1243 
ndr_print_array_uint8(struct ndr_print * ndr,const char * name,const uint8_t * data,uint32_t count)1244 _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
1245 			   const uint8_t *data, uint32_t count)
1246 {
1247 	int i;
1248 #define _ONELINE_LIMIT 32
1249 
1250 	if (data == NULL) {
1251 		ndr->print(ndr, "%s: ARRAY(%d) : NULL", name, count);
1252 		return;
1253 	}
1254 
1255 	if (NDR_HIDE_SECRET(ndr)) {
1256 		ndr->print(ndr, "%s: ARRAY(%d): <REDACTED SECRET VALUES>", name, count);
1257 		return;
1258 	}
1259 
1260 	if (count <= _ONELINE_LIMIT && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
1261 		char s[(_ONELINE_LIMIT + 1) * 2];
1262 		for (i=0;i<count;i++) {
1263 			snprintf(&s[i*2], 3, "%02x", data[i]);
1264 		}
1265 		s[i*2] = 0;
1266 		ndr->print(ndr, "%-25s: %s", name, s);
1267 		return;
1268 	}
1269 
1270 	ndr->print(ndr, "%s: ARRAY(%d)", name, count);
1271 	if (count > _ONELINE_LIMIT && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
1272 		ndr_dump_data(ndr, data, count);
1273 		return;
1274 	}
1275 
1276 	ndr->depth++;
1277 	for (i=0;i<count;i++) {
1278 		char *idx=NULL;
1279 		if (asprintf(&idx, "[%d]", i) != -1) {
1280 			ndr_print_uint8(ndr, idx, data[i]);
1281 			free(idx);
1282 		}
1283 	}
1284 	ndr->depth--;
1285 #undef _ONELINE_LIMIT
1286 }
1287 
ndr_print_dump_data_cb(const char * buf,void * private_data)1288 static void ndr_print_dump_data_cb(const char *buf, void *private_data)
1289 {
1290 	struct ndr_print *ndr = (struct ndr_print *)private_data;
1291 
1292 	ndr->print(ndr, "%s", buf);
1293 }
1294 
1295 /*
1296   ndr_print version of dump_data()
1297  */
ndr_dump_data(struct ndr_print * ndr,const uint8_t * buf,int len)1298 static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len)
1299 {
1300 	if (NDR_HIDE_SECRET(ndr)) {
1301 		return;
1302 	}
1303 	ndr->no_newline = true;
1304 	dump_data_cb(buf, len, true, ndr_print_dump_data_cb, ndr);
1305 	ndr->no_newline = false;
1306 }
1307 
1308 
ndr_print_DATA_BLOB(struct ndr_print * ndr,const char * name,DATA_BLOB r)1309 _PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
1310 {
1311 	ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length);
1312 	if (r.length) {
1313 		ndr_dump_data(ndr, r.data, r.length);
1314 	}
1315 }
1316 
1317 
1318 /*
1319  * Push a DATA_BLOB onto the wire.
1320  * 1) When called with LIBNDR_FLAG_ALIGN* alignment flags set, push padding
1321  *    bytes _only_. The length is determined by the alignment required and the
1322  *    current ndr offset.
1323  * 2) When called with the LIBNDR_FLAG_REMAINING flag, push the byte array to
1324  *    the ndr buffer.
1325  * 3) Otherwise, push a uint3264 length _and_ a corresponding byte array to the
1326  *    ndr buffer.
1327  */
ndr_push_DATA_BLOB(struct ndr_push * ndr,int ndr_flags,DATA_BLOB blob)1328 _PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
1329 {
1330 	if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1331 		/* nothing to do */
1332 	} else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
1333 		if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1334 			blob.length = NDR_ALIGN(ndr, 2);
1335 		} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1336 			blob.length = NDR_ALIGN(ndr, 4);
1337 		} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1338 			blob.length = NDR_ALIGN(ndr, 8);
1339 		}
1340 		NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
1341 		data_blob_clear(&blob);
1342 	} else {
1343 		NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, blob.length));
1344 	}
1345 	NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
1346 	return NDR_ERR_SUCCESS;
1347 }
1348 
1349 /*
1350  * Pull a DATA_BLOB from the wire.
1351  * 1) when called with LIBNDR_FLAG_ALIGN* alignment flags set, pull padding
1352  *    bytes _only_. The length is determined by the alignment required and the
1353  *    current ndr offset.
1354  * 2) When called with the LIBNDR_FLAG_REMAINING flag, pull all remaining bytes
1355  *    from the ndr buffer.
1356  * 3) Otherwise, pull a uint3264 length _and_ a corresponding byte array from the
1357  *    ndr buffer.
1358  */
ndr_pull_DATA_BLOB(struct ndr_pull * ndr,int ndr_flags,DATA_BLOB * blob)1359 _PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
1360 {
1361 	uint32_t length = 0;
1362 
1363 	if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1364 		length = ndr->data_size - ndr->offset;
1365 	} else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
1366 		if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1367 			length = NDR_ALIGN(ndr, 2);
1368 		} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1369 			length = NDR_ALIGN(ndr, 4);
1370 		} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1371 			length = NDR_ALIGN(ndr, 8);
1372 		}
1373 		if (ndr->data_size - ndr->offset < length) {
1374 			length = ndr->data_size - ndr->offset;
1375 		}
1376 	} else {
1377 		NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length));
1378 	}
1379 	NDR_PULL_NEED_BYTES(ndr, length);
1380 	*blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
1381 	ndr->offset += length;
1382 	return NDR_ERR_SUCCESS;
1383 }
1384 
ndr_size_DATA_BLOB(int ret,const DATA_BLOB * data,int flags)1385 _PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
1386 {
1387 	if (!data) return ret;
1388 	return ret + data->length;
1389 }
1390 
ndr_print_bool(struct ndr_print * ndr,const char * name,const bool b)1391 _PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b)
1392 {
1393 	ndr->print(ndr, "%-25s: %s", name, b?"true":"false");
1394 }
1395 
ndr_map_error2ntstatus(enum ndr_err_code ndr_err)1396 _PUBLIC_ NTSTATUS ndr_map_error2ntstatus(enum ndr_err_code ndr_err)
1397 {
1398 	switch (ndr_err) {
1399 	case NDR_ERR_SUCCESS:
1400 		return NT_STATUS_OK;
1401 	case NDR_ERR_BUFSIZE:
1402 		return NT_STATUS_BUFFER_TOO_SMALL;
1403 	case NDR_ERR_TOKEN:
1404 		return NT_STATUS_INTERNAL_ERROR;
1405 	case NDR_ERR_ALLOC:
1406 		return NT_STATUS_NO_MEMORY;
1407 	case NDR_ERR_ARRAY_SIZE:
1408 		return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
1409 	case NDR_ERR_INVALID_POINTER:
1410 		return NT_STATUS_INVALID_PARAMETER_MIX;
1411 	case NDR_ERR_UNREAD_BYTES:
1412 		return NT_STATUS_PORT_MESSAGE_TOO_LONG;
1413 	default:
1414 		break;
1415 	}
1416 
1417 	/* we should map all error codes to different status codes */
1418 	return NT_STATUS_INVALID_PARAMETER;
1419 }
1420 
ndr_map_error2errno(enum ndr_err_code ndr_err)1421 _PUBLIC_ int ndr_map_error2errno(enum ndr_err_code ndr_err)
1422 {
1423 	switch (ndr_err) {
1424 	case NDR_ERR_SUCCESS:
1425 		return 0;
1426 	case NDR_ERR_BUFSIZE:
1427 		return ENOSPC;
1428 	case NDR_ERR_TOKEN:
1429 		return EINVAL;
1430 	case NDR_ERR_ALLOC:
1431 		return ENOMEM;
1432 	case NDR_ERR_ARRAY_SIZE:
1433 		return EMSGSIZE;
1434 	case NDR_ERR_INVALID_POINTER:
1435 		return EINVAL;
1436 	case NDR_ERR_UNREAD_BYTES:
1437 		return EOVERFLOW;
1438 	default:
1439 		break;
1440 	}
1441 
1442 	/* we should map all error codes to different status codes */
1443 	return EINVAL;
1444 }
1445 
ndr_push_timespec(struct ndr_push * ndr,int ndr_flags,const struct timespec * t)1446 _PUBLIC_ enum ndr_err_code ndr_push_timespec(struct ndr_push *ndr,
1447 					     int ndr_flags,
1448 					     const struct timespec *t)
1449 {
1450 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
1451 	NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t->tv_sec));
1452 	NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, t->tv_nsec));
1453 	return NDR_ERR_SUCCESS;
1454 }
1455 
ndr_pull_timespec(struct ndr_pull * ndr,int ndr_flags,struct timespec * t)1456 _PUBLIC_ enum ndr_err_code ndr_pull_timespec(struct ndr_pull *ndr,
1457 					     int ndr_flags,
1458 					     struct timespec *t)
1459 {
1460 	uint64_t secs = 0;
1461 	uint32_t nsecs = 0;
1462 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
1463 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &secs));
1464 	NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &nsecs));
1465 	t->tv_sec = secs;
1466 	t->tv_nsec = nsecs;
1467 	return NDR_ERR_SUCCESS;
1468 }
1469 
ndr_print_timespec(struct ndr_print * ndr,const char * name,const struct timespec * t)1470 _PUBLIC_ void ndr_print_timespec(struct ndr_print *ndr, const char *name,
1471 				 const struct timespec *t)
1472 {
1473 	char *str = timestring(ndr, t->tv_sec);
1474 	ndr->print(ndr, "%-25s: %s.%ld", name, str, t->tv_nsec);
1475 	TALLOC_FREE(str);
1476 }
1477 
ndr_push_timeval(struct ndr_push * ndr,int ndr_flags,const struct timeval * t)1478 _PUBLIC_ enum ndr_err_code ndr_push_timeval(struct ndr_push *ndr,
1479 					    int ndr_flags,
1480 					    const struct timeval *t)
1481 {
1482 	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
1483 	NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t->tv_sec));
1484 	NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, t->tv_usec));
1485 	return NDR_ERR_SUCCESS;
1486 }
1487 
ndr_pull_timeval(struct ndr_pull * ndr,int ndr_flags,struct timeval * t)1488 _PUBLIC_ enum ndr_err_code ndr_pull_timeval(struct ndr_pull *ndr,
1489 					    int ndr_flags,
1490 					    struct timeval *t)
1491 {
1492 	uint64_t secs = 0;
1493 	uint32_t usecs = 0;
1494 	NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
1495 	NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, &secs));
1496 	NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &usecs));
1497 	t->tv_sec = secs;
1498 	t->tv_usec = usecs;
1499 	return NDR_ERR_SUCCESS;
1500 }
1501 
ndr_print_timeval(struct ndr_print * ndr,const char * name,const struct timeval * t)1502 _PUBLIC_ void ndr_print_timeval(struct ndr_print *ndr, const char *name,
1503 				const struct timeval *t)
1504 {
1505 	ndr->print(ndr, "%-25s: %s.%ld", name, timestring(ndr, t->tv_sec),
1506 		   (long)t->tv_usec);
1507 }
1508