1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <assert.h>
26 #include <strings.h>
27 #include <sys/param.h>
28
29 #include <smbsrv/libsmb.h>
30 #include <smbsrv/libmlrpc.h>
31
32 #ifdef _BIG_ENDIAN
33 static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN;
34 #else
35 static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN;
36 #endif
37
38 static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *);
39 static int ndr_decode_pac_hdr(ndr_stream_t *, ndr_pac_hdr_t *);
40
41 static int
ndr_encode_decode_common(ndr_stream_t * nds,unsigned opnum,ndr_typeinfo_t * ti,void * datum)42 ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum,
43 ndr_typeinfo_t *ti, void *datum)
44 {
45 int rc;
46
47 /*
48 * Perform the (un)marshalling
49 */
50 if (ndo_operation(nds, ti, opnum, datum))
51 return (NDR_DRC_OK);
52
53 switch (nds->error) {
54 case NDR_ERR_MALLOC_FAILED:
55 rc = NDR_DRC_FAULT_OUT_OF_MEMORY;
56 break;
57
58 case NDR_ERR_SWITCH_VALUE_INVALID:
59 rc = NDR_DRC_FAULT_PARAM_0_INVALID;
60 break;
61
62 case NDR_ERR_UNDERFLOW:
63 rc = NDR_DRC_FAULT_RECEIVED_RUNT;
64 break;
65
66 case NDR_ERR_GROW_FAILED:
67 rc = NDR_DRC_FAULT_ENCODE_TOO_BIG;
68 break;
69
70 default:
71 if (nds->m_op == NDR_M_OP_MARSHALL)
72 rc = NDR_DRC_FAULT_ENCODE_FAILED;
73 else
74 rc = NDR_DRC_FAULT_DECODE_FAILED;
75 break;
76 }
77
78 return (rc);
79 }
80
81 ndr_buf_t *
ndr_buf_init(ndr_typeinfo_t * ti)82 ndr_buf_init(ndr_typeinfo_t *ti)
83 {
84 ndr_buf_t *nbuf;
85
86 if ((nbuf = calloc(1, sizeof (ndr_buf_t))) == NULL)
87 return (NULL);
88
89 if ((nbuf->nb_heap = ndr_heap_create()) == NULL) {
90 free(nbuf);
91 return (NULL);
92 }
93
94 nbuf->nb_ti = ti;
95 nbuf->nb_magic = NDR_BUF_MAGIC;
96 return (nbuf);
97 }
98
99 void
ndr_buf_fini(ndr_buf_t * nbuf)100 ndr_buf_fini(ndr_buf_t *nbuf)
101 {
102 assert(nbuf->nb_magic == NDR_BUF_MAGIC);
103
104 nds_destruct(&nbuf->nb_nds);
105 ndr_heap_destroy(nbuf->nb_heap);
106 nbuf->nb_magic = 0;
107 free(nbuf);
108 }
109
110 /*
111 * Decode an NDR encoded buffer. The buffer is expected to contain
112 * a single fragment packet with a valid PDU header followed by NDR
113 * encoded data. The structure to which result points should be
114 * of the appropriate type to hold the decoded output. For example:
115 *
116 * pac_info_t info;
117 *
118 * if ((nbuf = ndr_buf_init(&TYPEINFO(ndr_pac)) != NULL) {
119 * rc = ndr_decode_buf(nbuf, opnum, data, datalen, &info);
120 * ...
121 * ndr_buf_fini(nbuf);
122 * }
123 */
124 int
ndr_buf_decode(ndr_buf_t * nbuf,unsigned hdr_type,unsigned opnum,const char * data,size_t datalen,void * result)125 ndr_buf_decode(ndr_buf_t *nbuf, unsigned hdr_type, unsigned opnum,
126 const char *data, size_t datalen, void *result)
127 {
128 ndr_common_header_t hdr;
129 ndr_pac_hdr_t pac_hdr;
130 unsigned pdu_size_hint;
131 int rc;
132
133 assert(nbuf->nb_magic == NDR_BUF_MAGIC);
134 assert(nbuf->nb_heap != NULL);
135 assert(nbuf->nb_ti != NULL);
136
137 if (datalen < NDR_PDU_SIZE_HINT_DEFAULT)
138 pdu_size_hint = NDR_PDU_SIZE_HINT_DEFAULT;
139 else
140 pdu_size_hint = datalen;
141
142 rc = nds_initialize(&nbuf->nb_nds, pdu_size_hint, NDR_MODE_BUF_DECODE,
143 nbuf->nb_heap);
144 if (NDR_DRC_IS_FAULT(rc))
145 return (rc);
146
147 bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen);
148
149 switch (hdr_type) {
150 case NDR_PTYPE_COMMON:
151 rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr);
152 if (NDR_DRC_IS_FAULT(rc))
153 return (rc);
154
155 if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags))
156 return (NDR_DRC_FAULT_DECODE_FAILED);
157 break;
158
159 case NDR_PTYPE_PAC:
160 rc = ndr_decode_pac_hdr(&nbuf->nb_nds, &pac_hdr);
161 if (NDR_DRC_IS_FAULT(rc))
162 return (rc);
163
164 if (pac_hdr.common_hdr.hdrlen != sizeof (ndr_serialtype1_hdr_t))
165 return (NDR_DRC_FAULT_DECODE_FAILED);
166 break;
167
168 default:
169 return (NDR_ERR_UNIMPLEMENTED);
170 }
171
172 rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti,
173 result);
174 return (rc);
175 }
176
177 /*
178 * Use the receive stream to unmarshall data (NDR_MODE_CALL_RECV).
179 */
180 int
ndr_decode_call(ndr_xa_t * mxa,void * params)181 ndr_decode_call(ndr_xa_t *mxa, void *params)
182 {
183 ndr_stream_t *nds = &mxa->recv_nds;
184 int rc;
185
186 if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_RECV))
187 return (NDR_DRC_FAULT_MODE_MISMATCH);
188
189 rc = ndr_encode_decode_common(nds, mxa->opnum,
190 mxa->binding->service->interface_ti, params);
191
192 return (rc + NDR_PTYPE_REQUEST);
193 }
194
195 /*
196 * Use the send stream to marshall data (NDR_MODE_RETURN_SEND).
197 */
198 int
ndr_encode_return(ndr_xa_t * mxa,void * params)199 ndr_encode_return(ndr_xa_t *mxa, void *params)
200 {
201 ndr_stream_t *nds = &mxa->send_nds;
202 int rc;
203
204 if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND))
205 return (NDR_DRC_FAULT_MODE_MISMATCH);
206
207 rc = ndr_encode_decode_common(nds, mxa->opnum,
208 mxa->binding->service->interface_ti, params);
209
210 return (rc + NDR_PTYPE_RESPONSE);
211 }
212
213 /*
214 * Use the send stream to marshall data (NDR_MODE_CALL_SEND).
215 */
216 int
ndr_encode_call(ndr_xa_t * mxa,void * params)217 ndr_encode_call(ndr_xa_t *mxa, void *params)
218 {
219 ndr_stream_t *nds = &mxa->send_nds;
220 int rc;
221
222 if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_SEND))
223 return (NDR_DRC_FAULT_MODE_MISMATCH);
224
225 rc = ndr_encode_decode_common(nds, mxa->opnum,
226 mxa->binding->service->interface_ti, params);
227
228 return (rc + NDR_PTYPE_REQUEST);
229 }
230
231 /*
232 * Use the receive stream to unmarshall data (NDR_MODE_RETURN_RECV).
233 */
234 int
ndr_decode_return(ndr_xa_t * mxa,void * params)235 ndr_decode_return(ndr_xa_t *mxa, void *params)
236 {
237 ndr_stream_t *nds = &mxa->recv_nds;
238 int rc;
239
240 if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_RECV))
241 return (NDR_DRC_FAULT_MODE_MISMATCH);
242
243 rc = ndr_encode_decode_common(nds, mxa->opnum,
244 mxa->binding->service->interface_ti, params);
245
246 return (rc + NDR_PTYPE_RESPONSE);
247 }
248
249 int
ndr_decode_pdu_hdr(ndr_xa_t * mxa)250 ndr_decode_pdu_hdr(ndr_xa_t *mxa)
251 {
252 ndr_common_header_t *hdr = &mxa->recv_hdr.common_hdr;
253 ndr_stream_t *nds = &mxa->recv_nds;
254 int rc;
255
256 rc = ndr_decode_hdr_common(nds, hdr);
257 if (NDR_DRC_IS_FAULT(rc))
258 return (rc);
259
260 /*
261 * Verify the protocol version.
262 */
263 if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0))
264 return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
265
266 mxa->ptype = hdr->ptype;
267 return (NDR_DRC_OK);
268 }
269
270 static int
ndr_decode_hdr_common(ndr_stream_t * nds,ndr_common_header_t * hdr)271 ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr)
272 {
273 int ptype;
274 int rc;
275 int charset;
276 int byte_order;
277
278 if (nds->m_op != NDR_M_OP_UNMARSHALL)
279 return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
280
281 /*
282 * All PDU headers are at least this big
283 */
284 rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0);
285 if (!rc)
286 return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT);
287
288 /*
289 * Peek at the first eight bytes to figure out what we're doing.
290 */
291 rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0);
292 if (!rc)
293 return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
294
295 /*
296 * Check for ASCII as the character set. This is an ASCII
297 * versus EBCDIC option and has nothing to do with Unicode.
298 */
299 charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK;
300 if (charset != NDR_REPLAB_CHAR_ASCII)
301 return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
302
303 /*
304 * Set the byte swap flag if the PDU byte-order
305 * is different from the local byte-order.
306 */
307 byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK;
308 nds->swap = (byte_order != ndr_native_byte_order) ? 1 : 0;
309
310 ptype = hdr->ptype;
311 if (ptype == NDR_PTYPE_REQUEST &&
312 (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) {
313 ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */
314 }
315
316 rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr);
317
318 return (NDR_DRC_PTYPE_RPCHDR(rc));
319 }
320
321 static int
ndr_decode_pac_hdr(ndr_stream_t * nds,ndr_pac_hdr_t * hdr)322 ndr_decode_pac_hdr(ndr_stream_t *nds, ndr_pac_hdr_t *hdr)
323 {
324 int rc;
325
326 if (nds->m_op != NDR_M_OP_UNMARSHALL)
327 return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
328
329 /*
330 * All PDU headers are at least this big
331 */
332 rc = NDS_GROW_PDU(nds, sizeof (ndr_pac_hdr_t), 0);
333 if (!rc)
334 return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT);
335
336 /*
337 * Peek at the first eight bytes to figure out what we're doing.
338 */
339 rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0);
340 if (!rc)
341 return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
342
343 /* Must be set to 1 to indicate type serialization version 1. */
344 if (hdr->common_hdr.version != 1)
345 return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
346
347 /*
348 * Set the byte swap flag if the PDU byte-order
349 * is different from the local byte-order.
350 */
351 nds->swap =
352 (hdr->common_hdr.endianness != ndr_native_byte_order) ? 1 : 0;
353
354 rc = ndr_encode_decode_common(nds, NDR_PTYPE_PAC,
355 &TYPEINFO(ndr_hdr), hdr);
356
357 return (NDR_DRC_PTYPE_RPCHDR(rc));
358 }
359
360 /*
361 * Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process
362 * the first fragment header then this function to process additional
363 * fragment headers.
364 */
365 void
ndr_decode_frag_hdr(ndr_stream_t * nds,ndr_common_header_t * hdr)366 ndr_decode_frag_hdr(ndr_stream_t *nds, ndr_common_header_t *hdr)
367 {
368 ndr_common_header_t *tmp;
369 uint8_t *pdu;
370 int byte_order;
371
372 pdu = (uint8_t *)nds->pdu_base_offset + nds->pdu_scan_offset;
373 bcopy(pdu, hdr, NDR_RSP_HDR_SIZE);
374
375 /*
376 * Swap non-byte fields if the PDU byte-order
377 * is different from the local byte-order.
378 */
379 byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK;
380
381 if (byte_order != ndr_native_byte_order) {
382 /*LINTED E_BAD_PTR_CAST_ALIGN*/
383 tmp = (ndr_common_header_t *)pdu;
384
385 nds_bswap(&tmp->frag_length, &hdr->frag_length,
386 sizeof (WORD));
387 nds_bswap(&tmp->auth_length, &hdr->auth_length,
388 sizeof (WORD));
389 nds_bswap(&tmp->call_id, &hdr->call_id, sizeof (DWORD));
390 }
391 }
392
393 /*
394 * Remove an RPC fragment header from the received data stream.
395 *
396 * NDR stream on entry:
397 *
398 * |<--- frag --->|
399 * +-----+--------+-----+--------+-----+---------+-----+
400 * | hdr | data | hdr | data | hdr | data | ... |
401 * +-----+--------+-----+--------+-----+---------+-----+
402 * <----
403 *
404 * NDR stream on return:
405 *
406 * +-----+----------------+-----+---------+-----+
407 * | hdr | data | hdr | data | ... |
408 * +-----+----------------+-----+---------+-----+
409 */
410 void
ndr_remove_frag_hdr(ndr_stream_t * nds)411 ndr_remove_frag_hdr(ndr_stream_t *nds)
412 {
413 char *hdr;
414 char *data;
415 int nbytes;
416
417 hdr = (char *)nds->pdu_base_offset + nds->pdu_scan_offset;
418 data = hdr + NDR_RSP_HDR_SIZE;
419 nbytes = nds->pdu_size - nds->pdu_scan_offset - NDR_RSP_HDR_SIZE;
420
421 bcopy(data, hdr, nbytes);
422 nds->pdu_size -= NDR_RSP_HDR_SIZE;
423 }
424
425 void
ndr_show_hdr(ndr_common_header_t * hdr)426 ndr_show_hdr(ndr_common_header_t *hdr)
427 {
428 char *fragtype;
429
430 if (hdr == NULL) {
431 ndo_printf(NULL, NULL, "ndr hdr: <null>");
432 return;
433 }
434
435 if (NDR_IS_SINGLE_FRAG(hdr->pfc_flags))
436 fragtype = "single";
437 else if (NDR_IS_FIRST_FRAG(hdr->pfc_flags))
438 fragtype = "first";
439 else if (NDR_IS_LAST_FRAG(hdr->pfc_flags))
440 fragtype = "last";
441 else
442 fragtype = "intermediate";
443
444 ndo_printf(NULL, NULL,
445 "ndr hdr: %d.%d ptype=%d, %s frag (flags=0x%08x) len=%d",
446 hdr->rpc_vers, hdr->rpc_vers_minor, hdr->ptype,
447 fragtype, hdr->pfc_flags, hdr->frag_length);
448 }
449
450 int
ndr_encode_pdu_hdr(ndr_xa_t * mxa)451 ndr_encode_pdu_hdr(ndr_xa_t *mxa)
452 {
453 ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr;
454 ndr_stream_t *nds = &mxa->send_nds;
455 int ptype;
456 int rc;
457
458 if (nds->m_op != NDR_M_OP_MARSHALL)
459 return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
460
461 ptype = hdr->ptype;
462 if (ptype == NDR_PTYPE_REQUEST &&
463 (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) {
464 ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */
465 }
466
467 rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr);
468
469 return (NDR_DRC_PTYPE_RPCHDR(rc));
470 }
471
472 /*
473 * This is a hand-coded derivative of the automatically generated
474 * (un)marshalling routine for bind_ack headers. bind_ack headers
475 * have an interior conformant array, which is inconsistent with
476 * IDL/NDR rules.
477 */
478 extern struct ndr_typeinfo ndt__uchar;
479 extern struct ndr_typeinfo ndt__ushort;
480 extern struct ndr_typeinfo ndt__ulong;
481
482 int ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref);
483 ndr_typeinfo_t ndt__ndr_bind_ack_hdr = {
484 1, /* NDR version */
485 3, /* alignment */
486 NDR_F_STRUCT, /* flags */
487 ndr__ndr_bind_ack_hdr, /* ndr_func */
488 68, /* pdu_size_fixed_part */
489 0, /* pdu_size_variable_part */
490 68, /* c_size_fixed_part */
491 0, /* c_size_variable_part */
492 };
493
494 /*
495 * [_no_reorder]
496 */
497 int
ndr__ndr_bind_ack_hdr(ndr_ref_t * encl_ref)498 ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref)
499 {
500 ndr_stream_t *nds = encl_ref->stream;
501 struct ndr_bind_ack_hdr *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/
502 (struct ndr_bind_ack_hdr *)encl_ref->datum;
503 ndr_ref_t myref;
504 unsigned long offset;
505
506 bzero(&myref, sizeof (myref));
507 myref.enclosing = encl_ref;
508 myref.stream = encl_ref->stream;
509 myref.packed_alignment = 0;
510
511 /* do all members in order */
512 NDR_MEMBER(_ndr_common_header, common_hdr, 0UL);
513 NDR_MEMBER(_ushort, max_xmit_frag, 16UL);
514 NDR_MEMBER(_ushort, max_recv_frag, 18UL);
515 NDR_MEMBER(_ulong, assoc_group_id, 20UL);
516
517 /* port any is the conformant culprit */
518 offset = 24UL;
519
520 switch (nds->m_op) {
521 case NDR_M_OP_MARSHALL:
522 val->sec_addr.length =
523 strlen((char *)val->sec_addr.port_spec) + 1;
524 break;
525
526 case NDR_M_OP_UNMARSHALL:
527 break;
528
529 default:
530 NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID);
531 return (0);
532 }
533
534 NDR_MEMBER(_ushort, sec_addr.length, offset);
535 NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec,
536 offset+2UL, val->sec_addr.length);
537
538 offset += 2;
539 offset += val->sec_addr.length;
540 offset += NDR_ALIGN4(offset);
541
542 NDR_MEMBER(_ndr_p_result_list, p_result_list, offset);
543 return (1);
544 }
545
546 /*
547 * Assume a single presentation context element in the result list.
548 */
549 unsigned
ndr_bind_ack_hdr_size(ndr_xa_t * mxa)550 ndr_bind_ack_hdr_size(ndr_xa_t *mxa)
551 {
552 ndr_bind_ack_hdr_t *bahdr = &mxa->send_hdr.bind_ack_hdr;
553 unsigned offset;
554 unsigned length;
555
556 /* port any is the conformant culprit */
557 offset = 24UL;
558
559 length = strlen((char *)bahdr->sec_addr.port_spec) + 1;
560
561 offset += 2;
562 offset += length;
563 offset += NDR_ALIGN4(offset);
564 offset += sizeof (ndr_p_result_list_t);
565 return (offset);
566 }
567
568 /*
569 * This is a hand-coded derivative of the automatically generated
570 * (un)marshalling routine for alter_context_rsp headers.
571 * Alter context response headers have an interior conformant array,
572 * which is inconsistent with IDL/NDR rules.
573 */
574 int ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref);
575 ndr_typeinfo_t ndt__ndr_alter_context_rsp_hdr = {
576 1, /* NDR version */
577 3, /* alignment */
578 NDR_F_STRUCT, /* flags */
579 ndr__ndr_alter_context_rsp_hdr, /* ndr_func */
580 56, /* pdu_size_fixed_part */
581 0, /* pdu_size_variable_part */
582 56, /* c_size_fixed_part */
583 0, /* c_size_variable_part */
584 };
585
586 /*
587 * [_no_reorder]
588 */
589 int
ndr__ndr_alter_context_rsp_hdr(ndr_ref_t * encl_ref)590 ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref)
591 {
592 ndr_stream_t *nds = encl_ref->stream;
593 ndr_alter_context_rsp_hdr_t *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/
594 (ndr_alter_context_rsp_hdr_t *)encl_ref->datum;
595 ndr_ref_t myref;
596 unsigned long offset;
597
598 bzero(&myref, sizeof (myref));
599 myref.enclosing = encl_ref;
600 myref.stream = encl_ref->stream;
601 myref.packed_alignment = 0;
602
603 /* do all members in order */
604 NDR_MEMBER(_ndr_common_header, common_hdr, 0UL);
605 NDR_MEMBER(_ushort, max_xmit_frag, 16UL);
606 NDR_MEMBER(_ushort, max_recv_frag, 18UL);
607 NDR_MEMBER(_ulong, assoc_group_id, 20UL);
608
609 offset = 24UL; /* offset of sec_addr */
610
611 switch (nds->m_op) {
612 case NDR_M_OP_MARSHALL:
613 val->sec_addr.length = 0;
614 break;
615
616 case NDR_M_OP_UNMARSHALL:
617 break;
618
619 default:
620 NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID);
621 return (0);
622 }
623
624 NDR_MEMBER(_ushort, sec_addr.length, offset);
625 NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec,
626 offset+2UL, val->sec_addr.length);
627
628 offset += 2; /* sizeof (sec_addr.length) */
629 offset += NDR_ALIGN4(offset);
630
631 NDR_MEMBER(_ndr_p_result_list, p_result_list, offset);
632 return (1);
633 }
634
635 /*
636 * Assume a single presentation context element in the result list.
637 */
638 unsigned
ndr_alter_context_rsp_hdr_size(void)639 ndr_alter_context_rsp_hdr_size(void)
640 {
641 unsigned offset;
642
643 offset = 24UL; /* offset of sec_addr */
644 offset += 2; /* sizeof (sec_addr.length) */
645 offset += NDR_ALIGN4(offset);
646 offset += sizeof (ndr_p_result_list_t);
647 return (offset);
648 }
649