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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 #ifndef _SMBSRV_NDR_H
  29 #define _SMBSRV_NDR_H
  30 
  31 /*
  32  * Network Data Representation (NDR) is a compatible subset of DCE RPC
  33  * and MSRPC NDR.  NDR is used to move parameters consisting of
  34  * complicated trees of data constructs between an RPC client and server.
  35  *
  36  * CAE Specification (1997)
  37  * DCE 1.1: Remote Procedure Call
  38  * Document Number: C706
  39  * The Open Group
  40  * ogspecs@opengroup.org
  41  */
  42 
  43 #if defined(_KERNEL) || defined(_FAKE_KERNEL)
  44 #error "not used in kernel code"
  45 #else /* _KERNEL */
  46 #include <sys/types.h>
  47 #include <sys/uio.h>
  48 #include <syslog.h>
  49 #include <stdlib.h>
  50 #include <string.h>
  51 #include <smbsrv/wintypes.h>
  52 #include <smbsrv/ndl/rpcpdu.ndl>
  53 #include <smbsrv/string.h>
  54 #endif  /* _KERNEL */
  55 
  56 #ifdef __cplusplus
  57 extern "C" {
  58 #endif
  59 
  60 /*
  61  * Normal sequence:
  62  *      - Application calls client-side stub w/ TOP-MOST arg structure
  63  *      - client stub performs NDR_M_OP_MARSHALL+NDR_DIR_IN
  64  *      - PDU conveyed (request, aka call, aka query)
  65  *      - server stub performs NDR_M_OP_UNMARSHALL+NDR_DIR_IN
  66  *      - server function called w/ TOP-MOST arg structure
  67  *      - server function returns w/ TOP-MOST arg structure modified
  68  *      - server stub performs NDR_M_OP_MARSHALL+NDR_DIR_OUT
  69  *      - PDU conveyed (reply, aka result, aka response)
  70  *      - client stub performs NDR_M_OP_UNMARSHALL+NDR_DIR_OUT
  71  *      - return to Application w/ TOP-MOST arg structure modified
  72  *
  73  * An interface is a sequence of top-most constructs.  Each top-most
  74  * construct corresponds to one parameter, either argument or return
  75  * value.
  76  *
  77  * A top-most construct is a sequence of outer constructs.  The first
  78  * outer construct is the referent of the argument, and the subsequent
  79  * outer constructs are descendents referenced by pointers from prior
  80  * constructs.
  81  *
  82  * An outer construct is a sequence of variable-sized info, fixed-sized
  83  * data, and variable-sized data.
  84  */
  85 
  86 /*
  87  * Terminology
  88  *
  89  * The ALL UPPER CASE terms recur in the DCE/RPC documentation.
  90  * The mixed-case names have been introduced as a reading aid.
  91  *
  92  * Size         The size of an array in elements. Think of this
  93  *              as the amount to malloc().
  94  *
  95  * Length       The number of elements of an array which are significant
  96  *              Think of this as the amount to bcopy().
  97  *
  98  * Known        Size/length is known at build time.
  99  *
 100  * Determined   Size/length is determined at run time.
 101  *
 102  * FIXED        The Size and Length are Known.
 103  *              Think of this as a string constant or a DOS 8.3 file name.
 104  *              char array[] = "A Constant Size/Length";
 105  *
 106  * CONFORMANT   The Size is Determined. Length is the same as Size.
 107  *              Think of this as strdup().
 108  *              char *array = strdup("Something");
 109  *
 110  * VARYING      The Size is Known. The Length is determined.
 111  *              Think of this as a strcpy() of a variable length string
 112  *              into a fixed length buffer:
 113  *              char array[100];
 114  *              strcpy(array, "very short string");
 115  *
 116  * VARYING/CONFORMANT
 117  *              The Size is Determined. The Length is separately Determined.
 118  *              Think of this like:
 119  *              char *array = malloc(size);
 120  *              strcpy(array, "short string");
 121  *
 122  * STRING       Strings can be CONFORMANT, VARYING, or CONFORMANT/VARYING.
 123  *              A string is fundamentally an array with the last
 124  *              significant element some sort of NULL.
 125  */
 126 
 127 #define NDR_F_NONE              0x0000  /* no flags */
 128 #define NDR_F_PARAMS_MASK       0x00FF
 129 #define NDR_F_SIZE_IS           0x0001  /* [size_is(X)] required/given */
 130 #define NDR_F_LENGTH_IS         0x0002  /* not implemented */
 131 #define NDR_F_SWITCH_IS         0x0004  /* [switch_is(X)] req./given */
 132 #define NDR_F_IS_STRING         0x0008  /* [string] req./given */
 133 #define NDR_F_IS_POINTER        0x0010  /* TYPE * ... req./given */
 134 #define NDR_F_IS_REFERENCE      0x0020  /* TYPE & ... req./given */
 135 #define NDR_F_DIMENSION_IS      0x0040  /* TYPE [N] req./given */
 136 
 137 #define NDR_F_WHENCE_MASK       0x00F0
 138 #define NDR_F_BACKPTR           0x0010  /* ref cause by pointer */
 139 #define NDR_F_OUTER             0x0020  /* ref caused by outer */
 140 #define NDR_F_TOPMOST           0x0040  /* ref caused by topmost */
 141 
 142 #define NDR_F_TYPEOP_MASK       0x0F00
 143 #define NDR_F_ARRAY             0x0100  /* type is array of somethings */
 144 #define NDR_F_POINTER           0x0200  /* type is pointer to something(s) */
 145 #define NDR_F_STRING            0x0300  /* type is string of somethings */
 146 #define NDR_F_UNION             0x0400  /* type is a union */
 147 #define NDR_F_STRUCT            0x0500  /* type is a structure */
 148 #define NDR_F_OPERATION         0x0600  /* type is a structure, special */
 149 #define NDR_F_INTERFACE         0x0700  /* type is a union, special */
 150 #define NDR_F_CONFORMANT        0x1000  /* struct conforming (var-size tail) */
 151 #define NDR_F_VARYING           0x2000  /* not implemented */
 152 
 153 struct ndr_heap;
 154 struct ndr_stream;
 155 struct ndr_reference;
 156 
 157 typedef uint16_t ndr_wchar_t;
 158 
 159 typedef struct ndr_typeinfo {
 160         unsigned char           version;        /* sanity check */
 161         unsigned char           alignment;      /* mask */
 162         unsigned short          type_flags;     /* NDR_F_... */
 163         int                     (*ndr_func)(struct ndr_reference *);
 164         unsigned short          pdu_size_fixed_part;
 165         unsigned short          pdu_size_variable_part;
 166         unsigned short          c_size_fixed_part;
 167         unsigned short          c_size_variable_part;
 168 } ndr_typeinfo_t;
 169 
 170 typedef struct ndr_reference {
 171         struct ndr_reference    *next;          /* queue list (outer only) */
 172         struct ndr_reference    *enclosing;     /* e.g. struct for this memb */
 173         struct ndr_stream       *stream;        /* root of NDR */
 174         ndr_typeinfo_t          *ti;            /* type of data referenced */
 175         char                    *name;          /* name of this member */
 176         unsigned long           pdu_offset;     /* referent in stub data */
 177         char                    *datum;         /* referent in local memory */
 178         char                    **backptr;      /* referer to set */
 179         unsigned short          outer_flags;    /* XXX_is() from top level */
 180         unsigned short          inner_flags;    /* XXX_is() in encapsulated */
 181         unsigned short          type_flags;     /* "requires" */
 182         unsigned short          packed_alignment;
 183         unsigned long           size_is;        /* conforming constructs */
 184         unsigned long           strlen_is;      /* strings */
 185         unsigned long           switch_is;      /* union arg selector */
 186         unsigned long           dimension_is;   /* fixed-len array size */
 187         unsigned long           pdu_end_offset; /* offset for limit of PDU */
 188 } ndr_ref_t;
 189 
 190 /*
 191  * For all operations, the ndr_stream, which is the root of NDR processing,
 192  * is the primary object.  When available, the appropriate ndr_ref_t
 193  * is passed, NULL otherwise.  Functions that return 'int' should return
 194  * TRUE (!0) or FALSE (0).  When functions return FALSE, including
 195  * ndo_malloc() returning NULL, they should set the stream->error to an
 196  * appropriate indicator of what went wrong.
 197  *
 198  * Functions ndo_get_pdu(), ndo_put_pdu(), and ndo_pad_pdu() must
 199  * never grow the PDU data.  A request for out-of-bounds data is an error.
 200  * The swap_bytes flag is 1 if NDR knows that the byte-order in the PDU
 201  * is different from the local system.  ndo_pad_pdu() advised that the
 202  * affected bytes should be zero filled.
 203  */
 204 typedef struct ndr_stream_ops {
 205         char *(*ndo_malloc)(struct ndr_stream *, unsigned, ndr_ref_t *);
 206         int (*ndo_free)(struct ndr_stream *, char *, ndr_ref_t *);
 207         int (*ndo_grow_pdu)(struct ndr_stream *, unsigned long, ndr_ref_t *);
 208         int (*ndo_pad_pdu)(struct ndr_stream *, unsigned long,
 209             unsigned long, ndr_ref_t *);
 210         int (*ndo_get_pdu)(struct ndr_stream *, unsigned long,
 211             unsigned long, char *, int, ndr_ref_t *);
 212         int (*ndo_put_pdu)(struct ndr_stream *, unsigned long,
 213             unsigned long, char *, int, ndr_ref_t *);
 214         void (*ndo_tattle)(struct ndr_stream *, char *, ndr_ref_t *);
 215         void (*ndo_tattle_error)(struct ndr_stream *, ndr_ref_t *);
 216         int (*ndo_reset)(struct ndr_stream *);
 217         void (*ndo_destruct)(struct ndr_stream *);
 218 } ndr_stream_ops_t;
 219 
 220 #define NDS_MALLOC(NDS, LEN, REF) \
 221         (*(NDS)->ndo->ndo_malloc)(NDS, LEN, REF)
 222 #define NDS_GROW_PDU(NDS, WANT_END_OFF, REF) \
 223         (*(NDS)->ndo->ndo_grow_pdu)(NDS, WANT_END_OFF, REF)
 224 #define NDS_PAD_PDU(NDS, PDU_OFFSET, N_BYTES, REF) \
 225         (*(NDS)->ndo->ndo_pad_pdu)(NDS, PDU_OFFSET, N_BYTES, REF)
 226 #define NDS_GET_PDU(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF) \
 227         (*(NDS)->ndo->ndo_get_pdu)(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF)
 228 #define NDS_PUT_PDU(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF) \
 229         (*(NDS)->ndo->ndo_put_pdu)(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF)
 230 #define NDS_TATTLE(NDS, WHAT, REF) \
 231         (*(NDS)->ndo->ndo_tattle)(NDS, WHAT, REF)
 232 #define NDS_TATTLE_ERROR(NDS, WHAT, REF) \
 233         (*(NDS)->ndo->ndo_tattle_error)(NDS, REF)
 234 #define NDS_RESET(NDS)          (*(NDS)->ndo->ndo_reset)(NDS)
 235 #define NDS_DESTRUCT(NDS)       (*(NDS)->ndo->ndo_destruct)(NDS)
 236 
 237 typedef struct ndr_stream {
 238         unsigned long           pdu_size;
 239         unsigned long           pdu_max_size;
 240         unsigned long           pdu_base_offset;
 241         unsigned long           pdu_scan_offset;
 242         unsigned char           *pdu_base_addr;
 243 
 244         ndr_stream_ops_t        *ndo;
 245 
 246         unsigned char           m_op;
 247         unsigned char           dir;
 248         unsigned char           swap;           /* native/net endian swap */
 249         unsigned char           flags;
 250         short                   error;
 251         short                   error_ref;
 252 
 253         ndr_ref_t *outer_queue_head;
 254         ndr_ref_t **outer_queue_tailp;
 255         ndr_ref_t *outer_current;
 256         struct ndr_heap *heap;
 257 } ndr_stream_t;
 258 
 259 #define NDR_M_OP_NONE           0x00
 260 #define NDR_M_OP_MARSHALL       0x01    /* data moving from datum to PDU */
 261 #define NDR_M_OP_UNMARSHALL     0x02    /* data moving from PDU to datum */
 262 
 263 #define NDR_DIR_NONE            0x00
 264 #define NDR_DIR_IN              0x10    /* data moving from caller to callee */
 265 #define NDR_DIR_OUT             0x20    /* data moving from callee to caller */
 266 
 267 #define NDR_MODE_CALL_SEND      (NDR_M_OP_MARSHALL + NDR_DIR_IN)
 268 #define NDR_MODE_CALL_RECV      (NDR_M_OP_UNMARSHALL + NDR_DIR_IN)
 269 #define NDR_MODE_RETURN_SEND    (NDR_M_OP_MARSHALL + NDR_DIR_OUT)
 270 #define NDR_MODE_RETURN_RECV    (NDR_M_OP_UNMARSHALL + NDR_DIR_OUT)
 271 #define NDR_MODE_BUF_ENCODE     NDR_MODE_CALL_SEND
 272 #define NDR_MODE_BUF_DECODE     NDR_MODE_RETURN_RECV
 273 
 274 #define NDR_MODE_TO_M_OP(MODE)  ((MODE) & 0x0F)
 275 #define NDR_MODE_TO_DIR(MODE)   ((MODE) & 0xF0)
 276 #define NDR_M_OP_AND_DIR_TO_MODE(M_OP, DIR)     ((M_OP)|(DIR))
 277 
 278 #define NDR_MODE_MATCH(NDS, MODE) \
 279         (NDR_M_OP_AND_DIR_TO_MODE((NDS)->m_op, (NDS)->dir) == (MODE))
 280 
 281 #define NDR_IS_FIRST_FRAG(F)    ((F) & NDR_PFC_FIRST_FRAG)
 282 #define NDR_IS_LAST_FRAG(F)     ((F) & NDR_PFC_LAST_FRAG)
 283 #define NDR_IS_SINGLE_FRAG(F)   \
 284         (NDR_IS_FIRST_FRAG((F)) && NDR_IS_LAST_FRAG((F)))
 285 
 286 #define NDS_F_NONE              0x00
 287 #define NDS_F_NOTERM            0x01    /* strings are not null terminated */
 288 #define NDS_F_NONULL            0x02    /* strings: no null on size_is */
 289 #define NDS_SETF(S, F)          ((S)->flags |= (F))
 290 #define NDS_CLEARF(S, F)        ((S)->flags &= ~(F))
 291 
 292 #define NDR_ERR_MALLOC_FAILED           -1
 293 #define NDR_ERR_M_OP_INVALID            -2
 294 #define NDR_ERR_UNDERFLOW               -3
 295 #define NDR_ERR_GROW_FAILED             -4      /* overflow */
 296 #define NDR_ERR_PAD_FAILED              -5      /* couldn't possibly happen */
 297 #define NDR_ERR_OUTER_HEADER_BAD        -6
 298 #define NDR_ERR_SWITCH_VALUE_ILLEGAL    -7
 299 #define NDR_ERR_SWITCH_VALUE_INVALID    -8
 300 #define NDR_ERR_SWITCH_VALUE_MISSING    -9
 301 #define NDR_ERR_SIZE_IS_MISMATCH_PDU    -10
 302 #define NDR_ERR_SIZE_IS_MISMATCH_AFTER  -11
 303 #define NDR_ERR_SIZE_IS_UNEXPECTED      -12
 304 #define NDR_ERR_SIZE_IS_DUPLICATED      -13
 305 #define NDR_ERR_OUTER_PARAMS_MISMATCH   -14
 306 #define NDR_ERR_ARRAY_VARLEN_ILLEGAL    -15
 307 #define NDR_ERR_ARRAY_UNION_ILLEGAL     -16
 308 #define NDR_ERR_OUTER_PARAMS_BAD        -17
 309 #define NDR_ERR_OUTER_UNION_ILLEGAL     -18
 310 #define NDR_ERR_TOPMOST_UNION_ILLEGAL   -19
 311 #define NDR_ERR_TOPMOST_VARLEN_ILLEGAL  -20
 312 #define NDR_ERR_INNER_PARAMS_BAD        -21
 313 #define NDR_ERR_UNIMPLEMENTED           -22
 314 #define NDR_ERR_NOT_AN_INTERFACE        -23
 315 #define NDR_ERR_STRLEN                  -24
 316 #define NDR_ERR_STRING_SIZING           -25
 317 #define NDR_ERR_BOUNDS_CHECK            -26
 318 
 319 #define NDR_SET_ERROR(REF, ERROR)                       \
 320         ((REF)->stream->error = (ERROR),          \
 321         (REF)->stream->error_ref = __LINE__,              \
 322         NDS_TATTLE_ERROR((REF)->stream, 0, REF))
 323 
 324 #define NDR_TATTLE(REF, WHAT) \
 325         (*(REF)->stream->ndo->ndo_tattle)((REF)->stream, WHAT, REF)
 326 
 327 #define MEMBER_STR(MEMBER) #MEMBER
 328 
 329 #define NDR_DIR_IS_IN  (encl_ref->stream->dir == NDR_DIR_IN)
 330 #define NDR_DIR_IS_OUT (encl_ref->stream->dir == NDR_DIR_OUT)
 331 
 332 #define NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 333                 ARGFLAGS, ARGMEM, ARGVAL) { \
 334                 myref.pdu_offset = encl_ref->pdu_offset + (OFFSET);  \
 335                 myref.name = MEMBER_STR(MEMBER);                        \
 336                 myref.datum = (char *)&val->MEMBER;                      \
 337                 myref.inner_flags = ARGFLAGS;                           \
 338                 myref.ti = &ndt_##TYPE;                                     \
 339                 myref.ARGMEM = ARGVAL;                                  \
 340                 if (!ndr_inner(&myref))                                     \
 341                         return (0);                                     \
 342         }
 343 
 344 #define NDR_MEMBER(TYPE, MEMBER, OFFSET) \
 345         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 346                 NDR_F_NONE, size_is, 0)
 347 
 348 #define NDR_MEMBER_ARR_WITH_SIZE_IS(TYPE, MEMBER, OFFSET, SIZE_IS) \
 349         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 350                 NDR_F_SIZE_IS, size_is, SIZE_IS)
 351 
 352 #define NDR_MEMBER_ARR_WITH_DIMENSION(TYPE, MEMBER, OFFSET, SIZE_IS) \
 353         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 354                 NDR_F_DIMENSION_IS, dimension_is, SIZE_IS)
 355 
 356 #define NDR_MEMBER_PTR_WITH_SIZE_IS(TYPE, MEMBER, OFFSET, SIZE_IS) \
 357         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 358                 NDR_F_SIZE_IS+NDR_F_IS_POINTER, size_is, SIZE_IS)
 359 
 360 #define NDR_MEMBER_PTR(TYPE, MEMBER, OFFSET)            \
 361         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET,       \
 362                 NDR_F_IS_POINTER, size_is, 0)
 363 
 364 #define NDR_MEMBER_WITH_SWITCH_IS(TYPE, MEMBER, OFFSET, SWITCH_IS)      \
 365         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET,                       \
 366                 NDR_F_SWITCH_IS, switch_is, SWITCH_IS)
 367 
 368 
 369 #define NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER, \
 370                 ARGFLAGS, ARGMEM, ARGVAL) { \
 371                 myref.pdu_offset = -1;                                  \
 372                 myref.name = MEMBER_STR(MEMBER);                        \
 373                 myref.datum = (char *)&val->MEMBER;                      \
 374                 myref.inner_flags = ARGFLAGS;                           \
 375                 myref.ti = &ndt_##TYPE;                                     \
 376                 myref.ARGMEM = ARGVAL;                                  \
 377                 if (!ndr_topmost(&myref))                           \
 378                         return (0);                                     \
 379         }
 380 
 381 #define NDR_TOPMOST_MEMBER(TYPE, MEMBER)                                \
 382         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 383                 NDR_F_NONE, size_is, 0)
 384 
 385 #define NDR_TOPMOST_MEMBER_ARR_WITH_SIZE_IS(TYPE, MEMBER, SIZE_IS)      \
 386         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 387                 NDR_F_SIZE_IS, size_is, SIZE_IS)
 388 
 389 #define NDR_TOPMOST_MEMBER_ARR_WITH_DIMENSION(TYPE, MEMBER, SIZE_IS)    \
 390         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 391                 NDR_F_DIMENSION_IS, dimension_is, SIZE_IS)
 392 
 393 #define NDR_TOPMOST_MEMBER_PTR_WITH_SIZE_IS(TYPE, MEMBER, SIZE_IS)      \
 394         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 395                 NDR_F_SIZE_IS+NDR_F_IS_POINTER, size_is, SIZE_IS)
 396 
 397 #define NDR_TOPMOST_MEMBER_PTR(TYPE, MEMBER)            \
 398         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,       \
 399                 NDR_F_IS_POINTER, size_is, 0)
 400 
 401 #define NDR_TOPMOST_MEMBER_REF(TYPE, MEMBER)            \
 402         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,       \
 403                 NDR_F_IS_REFERENCE, size_is, 0)
 404 
 405 #define NDR_TOPMOST_MEMBER_REF_WITH_SIZE_IS(TYPE, MEMBER, SIZE_IS)      \
 406         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 407                 NDR_F_SIZE_IS+NDR_F_IS_REFERENCE, size_is, SIZE_IS)
 408 
 409 #define NDR_TOPMOST_MEMBER_WITH_SWITCH_IS(TYPE, MEMBER, SWITCH_IS)      \
 410         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 411                 NDR_F_SWITCH_IS, switch_is, SWITCH_IS)
 412 
 413 /* this is assuming offset+0 */
 414 #define NDR_PARAMS_MEMBER_WITH_ARG(TYPE, MEMBER, ARGFLAGS, \
 415         ARGMEM, ARGVAL) { \
 416                 myref.pdu_offset = encl_ref->pdu_offset;             \
 417                 myref.name = MEMBER_STR(MEMBER);                        \
 418                 myref.datum = (char *)&val->MEMBER;                      \
 419                 myref.inner_flags = ARGFLAGS;                           \
 420                 myref.ti = &ndt_##TYPE;                                     \
 421                 myref.ARGMEM = ARGVAL;                                  \
 422                 if (!ndr_params(&myref))                            \
 423                         return (0);                                     \
 424         }
 425 
 426 #define NDR_PARAMS_MEMBER(TYPE, MEMBER)                 \
 427         NDR_PARAMS_MEMBER_WITH_ARG(TYPE, MEMBER,        \
 428         NDR_F_NONE, size_is, 0)
 429 
 430 #define NDR_STRING_DIM          1
 431 #define NDR_ANYSIZE_DIM         1
 432 
 433 int ndo_process(struct ndr_stream *, ndr_typeinfo_t *, char *);
 434 int ndo_operation(struct ndr_stream *, ndr_typeinfo_t *, int opnum, char *);
 435 void ndo_printf(struct ndr_stream *, ndr_ref_t *, const char *, ...);
 436 void ndo_trace(const char *);
 437 void ndo_fmt(struct ndr_stream *, ndr_ref_t *, char *);
 438 
 439 int ndr_params(ndr_ref_t *);
 440 int ndr_topmost(ndr_ref_t *);
 441 int ndr_run_outer_queue(struct ndr_stream *);
 442 int ndr_outer(ndr_ref_t *);
 443 int ndr_outer_fixed(ndr_ref_t *);
 444 int ndr_outer_fixed_array(ndr_ref_t *);
 445 int ndr_outer_conformant_array(ndr_ref_t *);
 446 int ndr_outer_conformant_construct(ndr_ref_t *);
 447 int ndr_size_is(ndr_ref_t *);
 448 int ndr_outer_string(ndr_ref_t *);
 449 int ndr_outer_peek_sizing(ndr_ref_t *, unsigned, unsigned long *);
 450 int ndr_outer_poke_sizing(ndr_ref_t *, unsigned, unsigned long *);
 451 int ndr_outer_align(ndr_ref_t *);
 452 int ndr_outer_grow(ndr_ref_t *, unsigned);
 453 int ndr_inner(ndr_ref_t *);
 454 int ndr_inner_pointer(ndr_ref_t *);
 455 int ndr_inner_reference(ndr_ref_t *);
 456 int ndr_inner_array(ndr_ref_t *);
 457 
 458 size_t ndr_mbstowcs(struct ndr_stream *, smb_wchar_t *, const char *, size_t);
 459 int ndr_mbtowc(struct ndr_stream *, smb_wchar_t *, const char *, size_t);
 460 
 461 void nds_bswap(void *src, void *dst, size_t len);
 462 
 463 #ifdef __cplusplus
 464 }
 465 #endif
 466 
 467 #endif /* _SMBSRV_NDR_H */