15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 227052Samw * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw #ifndef _LIBMLRPC_H 275331Samw #define _LIBMLRPC_H 285331Samw 297052Samw #include <sys/types.h> 30*8334SJose.Borrego@Sun.COM #include <sys/uio.h> 31*8334SJose.Borrego@Sun.COM #include <smbsrv/wintypes.h> 32*8334SJose.Borrego@Sun.COM #include <smbsrv/ndr.h> 33*8334SJose.Borrego@Sun.COM #include <smbsrv/smb_sid.h> 34*8334SJose.Borrego@Sun.COM #include <smbsrv/smb_xdr.h> 357052Samw 365331Samw #ifdef __cplusplus 375331Samw extern "C" { 385331Samw #endif 395331Samw 40*8334SJose.Borrego@Sun.COM /* 41*8334SJose.Borrego@Sun.COM * An MSRPC compatible implementation of OSF DCE RPC. DCE RPC is derived 42*8334SJose.Borrego@Sun.COM * from the Apollo Network Computing Architecture (NCA) RPC implementation. 43*8334SJose.Borrego@Sun.COM * 44*8334SJose.Borrego@Sun.COM * CAE Specification (1997) 45*8334SJose.Borrego@Sun.COM * DCE 1.1: Remote Procedure Call 46*8334SJose.Borrego@Sun.COM * Document Number: C706 47*8334SJose.Borrego@Sun.COM * The Open Group 48*8334SJose.Borrego@Sun.COM * ogspecs@opengroup.org 49*8334SJose.Borrego@Sun.COM * 50*8334SJose.Borrego@Sun.COM * This implementation is based on the DCE Remote Procedure Call spec with 51*8334SJose.Borrego@Sun.COM * enhancements to support Unicode strings. The diagram below shows the 52*8334SJose.Borrego@Sun.COM * DCE RPC layers compared against ONC SUN RPC. 53*8334SJose.Borrego@Sun.COM * 54*8334SJose.Borrego@Sun.COM * NDR RPC Layers Sun RPC Layers Remark 55*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ +---------------+ 56*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 57*8334SJose.Borrego@Sun.COM * | Application | | Application | The application 58*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 59*8334SJose.Borrego@Sun.COM * | Hand coded | | RPCGEN gen'd | Where the real 60*8334SJose.Borrego@Sun.COM * | client/server | | client/server | work happens 61*8334SJose.Borrego@Sun.COM * | srvsvc.ndl | | *_svc.c *_clnt| 62*8334SJose.Borrego@Sun.COM * | srvsvc.c | | | 63*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 64*8334SJose.Borrego@Sun.COM * | RPC Library | | RPC Library | Calls/Return 65*8334SJose.Borrego@Sun.COM * | ndr_*.c | | | Binding/PMAP 66*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 67*8334SJose.Borrego@Sun.COM * | RPC Protocol | | RPC Protocol | Headers, Auth, 68*8334SJose.Borrego@Sun.COM * | rpcpdu.ndl | | | 69*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 70*8334SJose.Borrego@Sun.COM * | IDL gen'd | | RPCGEN gen'd | Aggregate 71*8334SJose.Borrego@Sun.COM * | NDR stubs | | XDR stubs | Composition 72*8334SJose.Borrego@Sun.COM * | *__ndr.c | | *_xdr.c | 73*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 74*8334SJose.Borrego@Sun.COM * | NDR Represen | | XDR Represen | Byte order, padding 75*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 76*8334SJose.Borrego@Sun.COM * | Packet Heaps | | Network Conn | DCERPC does not talk 77*8334SJose.Borrego@Sun.COM * | ndo_*.c | | clnt_{tcp,udp}| directly to network. 78*8334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 79*8334SJose.Borrego@Sun.COM * 80*8334SJose.Borrego@Sun.COM * There are two major differences between the DCE RPC and ONC RPC: 81*8334SJose.Borrego@Sun.COM * 82*8334SJose.Borrego@Sun.COM * 1. NDR RPC only generates or processes packets from buffers. Other 83*8334SJose.Borrego@Sun.COM * layers must take care of packet transmission and reception. 84*8334SJose.Borrego@Sun.COM * The packet heaps are managed through a simple interface provided 85*8334SJose.Borrego@Sun.COM * by the Network Data Representation (NDR) module called ndr_stream_t. 86*8334SJose.Borrego@Sun.COM * ndo_*.c modules implement the different flavors (operations) of 87*8334SJose.Borrego@Sun.COM * packet heaps. 88*8334SJose.Borrego@Sun.COM * 89*8334SJose.Borrego@Sun.COM * ONC RPC communicates directly with the network. You have to do 90*8334SJose.Borrego@Sun.COM * something special for the RPC packet to be placed in a buffer 91*8334SJose.Borrego@Sun.COM * rather than sent to the wire. 92*8334SJose.Borrego@Sun.COM * 93*8334SJose.Borrego@Sun.COM * 2. NDR RPC uses application provided heaps to support operations. 94*8334SJose.Borrego@Sun.COM * A heap is a single, monolithic chunk of memory that NDR RPC manages 95*8334SJose.Borrego@Sun.COM * as it allocates. When the operation and its result are done, the 96*8334SJose.Borrego@Sun.COM * heap is disposed of as a single item. The transaction, which 97*8334SJose.Borrego@Sun.COM * is the anchor of most operations, contains the necessary book- 98*8334SJose.Borrego@Sun.COM * keeping for the heap. 99*8334SJose.Borrego@Sun.COM * 100*8334SJose.Borrego@Sun.COM * ONC RPC uses malloc() liberally throughout its run-time system. 101*8334SJose.Borrego@Sun.COM * To free results, ONC RPC supports an XDR_FREE operation that 102*8334SJose.Borrego@Sun.COM * traverses data structures freeing memory as it goes, whether 103*8334SJose.Borrego@Sun.COM * it was malloc'd or not. 104*8334SJose.Borrego@Sun.COM */ 105*8334SJose.Borrego@Sun.COM 106*8334SJose.Borrego@Sun.COM /* 107*8334SJose.Borrego@Sun.COM * Dispatch Return Code (DRC) 108*8334SJose.Borrego@Sun.COM * 109*8334SJose.Borrego@Sun.COM * 0x8000 15:01 Set to indicate a fault, clear indicates status 110*8334SJose.Borrego@Sun.COM * 0x7F00 08:07 Status/Fault specific 111*8334SJose.Borrego@Sun.COM * 0x00FF 00:08 PTYPE_... of PDU, 0xFF for header 112*8334SJose.Borrego@Sun.COM */ 113*8334SJose.Borrego@Sun.COM #define NDR_DRC_OK 0x0000 114*8334SJose.Borrego@Sun.COM #define NDR_DRC_MASK_FAULT 0x8000 115*8334SJose.Borrego@Sun.COM #define NDR_DRC_MASK_SPECIFIER 0xFF00 116*8334SJose.Borrego@Sun.COM #define NDR_DRC_MASK_PTYPE 0x00FF 117*8334SJose.Borrego@Sun.COM 118*8334SJose.Borrego@Sun.COM /* Fake PTYPE DRC discriminators */ 119*8334SJose.Borrego@Sun.COM #define NDR_DRC_PTYPE_RPCHDR(DRC) ((DRC) | 0x00FF) 120*8334SJose.Borrego@Sun.COM #define NDR_DRC_PTYPE_API(DRC) ((DRC) | 0x00AA) 121*8334SJose.Borrego@Sun.COM 122*8334SJose.Borrego@Sun.COM /* DRC Recognizers */ 123*8334SJose.Borrego@Sun.COM #define NDR_DRC_IS_OK(DRC) (((DRC) & NDR_DRC_MASK_SPECIFIER) == 0) 124*8334SJose.Borrego@Sun.COM #define NDR_DRC_IS_FAULT(DRC) (((DRC) & NDR_DRC_MASK_FAULT) != 0) 125*8334SJose.Borrego@Sun.COM 126*8334SJose.Borrego@Sun.COM /* 127*8334SJose.Borrego@Sun.COM * (Un)Marshalling category specifiers 128*8334SJose.Borrego@Sun.COM */ 129*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_MODE_MISMATCH 0x8100 130*8334SJose.Borrego@Sun.COM #define NDR_DRC_RECEIVED 0x0200 131*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RECEIVED_RUNT 0x8300 132*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RECEIVED_MALFORMED 0x8400 133*8334SJose.Borrego@Sun.COM #define NDR_DRC_DECODED 0x0500 134*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_DECODE_FAILED 0x8600 135*8334SJose.Borrego@Sun.COM #define NDR_DRC_ENCODED 0x0700 136*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_ENCODE_FAILED 0x8800 137*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_ENCODE_TOO_BIG 0x8900 138*8334SJose.Borrego@Sun.COM #define NDR_DRC_SENT 0x0A00 139*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_SEND_FAILED 0x8B00 140*8334SJose.Borrego@Sun.COM 141*8334SJose.Borrego@Sun.COM /* 142*8334SJose.Borrego@Sun.COM * Resource category specifier 143*8334SJose.Borrego@Sun.COM */ 144*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RESOURCE_1 0x9100 145*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RESOURCE_2 0x9200 146*8334SJose.Borrego@Sun.COM 147*8334SJose.Borrego@Sun.COM /* 148*8334SJose.Borrego@Sun.COM * Parameters. Usually #define'd with useful alias 149*8334SJose.Borrego@Sun.COM */ 150*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_0_INVALID 0xC000 151*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED 0xD000 152*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_1_INVALID 0xC100 153*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED 0xD100 154*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_2_INVALID 0xC200 155*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED 0xD200 156*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_3_INVALID 0xC300 157*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED 0xD300 158*8334SJose.Borrego@Sun.COM 159*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 160*8334SJose.Borrego@Sun.COM 161*8334SJose.Borrego@Sun.COM /* RPCHDR */ 162*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ 163*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ 164*8334SJose.Borrego@Sun.COM 165*8334SJose.Borrego@Sun.COM /* Request */ 166*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */ 167*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */ 168*8334SJose.Borrego@Sun.COM 169*8334SJose.Borrego@Sun.COM /* Bind */ 170*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */ 171*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */ 172*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */ 173*8334SJose.Borrego@Sun.COM #define NDR_DRC_BINDING_MADE 0x000B /* OK */ 174*8334SJose.Borrego@Sun.COM 175*8334SJose.Borrego@Sun.COM /* API */ 176*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */ 177*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA /* RESOURCE_1 */ 178*8334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA /* PARAM_1_INVALID */ 179*8334SJose.Borrego@Sun.COM 180*8334SJose.Borrego@Sun.COM struct ndr_xa; 181*8334SJose.Borrego@Sun.COM struct ndr_client; 182*8334SJose.Borrego@Sun.COM 183*8334SJose.Borrego@Sun.COM typedef struct ndr_stub_table { 184*8334SJose.Borrego@Sun.COM int (*func)(void *, struct ndr_xa *); 185*8334SJose.Borrego@Sun.COM unsigned short opnum; 186*8334SJose.Borrego@Sun.COM } ndr_stub_table_t; 187*8334SJose.Borrego@Sun.COM 188*8334SJose.Borrego@Sun.COM typedef struct ndr_service { 189*8334SJose.Borrego@Sun.COM char *name; 190*8334SJose.Borrego@Sun.COM char *desc; 191*8334SJose.Borrego@Sun.COM char *endpoint; 192*8334SJose.Borrego@Sun.COM char *sec_addr_port; 193*8334SJose.Borrego@Sun.COM char *abstract_syntax_uuid; 194*8334SJose.Borrego@Sun.COM int abstract_syntax_version; 195*8334SJose.Borrego@Sun.COM char *transfer_syntax_uuid; 196*8334SJose.Borrego@Sun.COM int transfer_syntax_version; 197*8334SJose.Borrego@Sun.COM unsigned bind_instance_size; 198*8334SJose.Borrego@Sun.COM int (*bind_req)(); 199*8334SJose.Borrego@Sun.COM int (*unbind_and_close)(); 200*8334SJose.Borrego@Sun.COM int (*call_stub)(struct ndr_xa *); 201*8334SJose.Borrego@Sun.COM ndr_typeinfo_t *interface_ti; 202*8334SJose.Borrego@Sun.COM ndr_stub_table_t *stub_table; 203*8334SJose.Borrego@Sun.COM } ndr_service_t; 204*8334SJose.Borrego@Sun.COM 205*8334SJose.Borrego@Sun.COM /* 206*8334SJose.Borrego@Sun.COM * The list of bindings is anchored at a connection. Nothing in the 207*8334SJose.Borrego@Sun.COM * RPC mechanism allocates them. Binding elements which have service==0 208*8334SJose.Borrego@Sun.COM * indicate free elements. When a connection is instantiated, at least 209*8334SJose.Borrego@Sun.COM * one free binding entry should also be established. Something like 210*8334SJose.Borrego@Sun.COM * this should suffice for most (all) situations: 211*8334SJose.Borrego@Sun.COM * 212*8334SJose.Borrego@Sun.COM * struct connection { 213*8334SJose.Borrego@Sun.COM * .... 214*8334SJose.Borrego@Sun.COM * ndr_binding_t *binding_list_head; 215*8334SJose.Borrego@Sun.COM * ndr_binding_t binding_pool[N_BINDING_POOL]; 216*8334SJose.Borrego@Sun.COM * .... 217*8334SJose.Borrego@Sun.COM * }; 218*8334SJose.Borrego@Sun.COM * 219*8334SJose.Borrego@Sun.COM * init_connection(struct connection *conn) { 220*8334SJose.Borrego@Sun.COM * .... 221*8334SJose.Borrego@Sun.COM * ndr_svc_binding_pool_init(&conn->binding_list_head, 222*8334SJose.Borrego@Sun.COM * conn->binding_pool, N_BINDING_POOL); 223*8334SJose.Borrego@Sun.COM */ 224*8334SJose.Borrego@Sun.COM typedef struct ndr_binding { 225*8334SJose.Borrego@Sun.COM struct ndr_binding *next; 226*8334SJose.Borrego@Sun.COM ndr_p_context_id_t p_cont_id; 227*8334SJose.Borrego@Sun.COM unsigned char which_side; 228*8334SJose.Borrego@Sun.COM struct ndr_client *clnt; 229*8334SJose.Borrego@Sun.COM ndr_service_t *service; 230*8334SJose.Borrego@Sun.COM void *instance_specific; 231*8334SJose.Borrego@Sun.COM } ndr_binding_t; 232*8334SJose.Borrego@Sun.COM 233*8334SJose.Borrego@Sun.COM #define NDR_BIND_SIDE_CLIENT 1 234*8334SJose.Borrego@Sun.COM #define NDR_BIND_SIDE_SERVER 2 235*8334SJose.Borrego@Sun.COM 236*8334SJose.Borrego@Sun.COM #define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \ 237*8334SJose.Borrego@Sun.COM ((TYPE *) (BINDING)->instance_specific) 238*8334SJose.Borrego@Sun.COM 239*8334SJose.Borrego@Sun.COM /* 240*8334SJose.Borrego@Sun.COM * The binding list space must be provided by the application library 241*8334SJose.Borrego@Sun.COM * for use by the underlying RPC library. We need at least two binding 242*8334SJose.Borrego@Sun.COM * slots per connection. 243*8334SJose.Borrego@Sun.COM */ 244*8334SJose.Borrego@Sun.COM #define NDR_N_BINDING_POOL 2 245*8334SJose.Borrego@Sun.COM 246*8334SJose.Borrego@Sun.COM typedef struct ndr_pipe { 247*8334SJose.Borrego@Sun.COM int np_fid; 248*8334SJose.Borrego@Sun.COM smb_opipe_context_t np_ctx; 249*8334SJose.Borrego@Sun.COM char *np_buf; 250*8334SJose.Borrego@Sun.COM struct uio np_uio; 251*8334SJose.Borrego@Sun.COM iovec_t np_iov; 252*8334SJose.Borrego@Sun.COM ndr_fraglist_t np_frags; 253*8334SJose.Borrego@Sun.COM int np_refcnt; 254*8334SJose.Borrego@Sun.COM uint16_t np_max_xmit_frag; 255*8334SJose.Borrego@Sun.COM uint16_t np_max_recv_frag; 256*8334SJose.Borrego@Sun.COM ndr_binding_t *np_binding; 257*8334SJose.Borrego@Sun.COM ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL]; 258*8334SJose.Borrego@Sun.COM } ndr_pipe_t; 259*8334SJose.Borrego@Sun.COM 260*8334SJose.Borrego@Sun.COM /* 261*8334SJose.Borrego@Sun.COM * Number of bytes required to align SIZE on the next dword/4-byte 262*8334SJose.Borrego@Sun.COM * boundary. 263*8334SJose.Borrego@Sun.COM */ 264*8334SJose.Borrego@Sun.COM #define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3); 265*8334SJose.Borrego@Sun.COM 266*8334SJose.Borrego@Sun.COM /* 267*8334SJose.Borrego@Sun.COM * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying 268*8334SJose.Borrego@Sun.COM * and conformant one-dimensional arrays. Characters can be single-byte 269*8334SJose.Borrego@Sun.COM * or multi-byte as long as all characters conform to a fixed element size, 270*8334SJose.Borrego@Sun.COM * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The 271*8334SJose.Borrego@Sun.COM * string is terminated by a null character of the appropriate element size. 272*8334SJose.Borrego@Sun.COM * 273*8334SJose.Borrego@Sun.COM * MSRPC strings should always be varying/conformant and not null terminated. 274*8334SJose.Borrego@Sun.COM * This format uses the size_is, first_is and length_is attributes (CAE 275*8334SJose.Borrego@Sun.COM * section 4.2.18). 276*8334SJose.Borrego@Sun.COM * 277*8334SJose.Borrego@Sun.COM * typedef struct string { 278*8334SJose.Borrego@Sun.COM * DWORD size_is; 279*8334SJose.Borrego@Sun.COM * DWORD first_is; 280*8334SJose.Borrego@Sun.COM * DWORD length_is; 281*8334SJose.Borrego@Sun.COM * wchar_t string[ANY_SIZE_ARRAY]; 282*8334SJose.Borrego@Sun.COM * } string_t; 283*8334SJose.Borrego@Sun.COM * 284*8334SJose.Borrego@Sun.COM * The size_is attribute is used to specify the number of data elements in 285*8334SJose.Borrego@Sun.COM * each dimension of an array. 286*8334SJose.Borrego@Sun.COM * 287*8334SJose.Borrego@Sun.COM * The first_is attribute is used to define the lower bound for significant 288*8334SJose.Borrego@Sun.COM * elements in each dimension of an array. For strings this is always 0. 289*8334SJose.Borrego@Sun.COM * 290*8334SJose.Borrego@Sun.COM * The length_is attribute is used to define the number of significant 291*8334SJose.Borrego@Sun.COM * elements in each dimension of an array. For strings this is typically 292*8334SJose.Borrego@Sun.COM * the same as size_is. Although it might be (size_is - 1) if the string 293*8334SJose.Borrego@Sun.COM * is null terminated. 294*8334SJose.Borrego@Sun.COM * 295*8334SJose.Borrego@Sun.COM * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes 296*8334SJose.Borrego@Sun.COM * +---------+---------+---------+------+------+------+------+ 297*8334SJose.Borrego@Sun.COM * |size_is |first_is |length_is| char | char | char | char | 298*8334SJose.Borrego@Sun.COM * +---------+---------+---------+------+------+------+------+ 299*8334SJose.Borrego@Sun.COM * 300*8334SJose.Borrego@Sun.COM * Unfortunately, not all MSRPC Unicode strings are null terminated, which 301*8334SJose.Borrego@Sun.COM * means that the recipient has to manually null-terminate the string after 302*8334SJose.Borrego@Sun.COM * it has been unmarshalled. There may be a wide-char pad following a 303*8334SJose.Borrego@Sun.COM * string, and it may sometimes contains zero, but it's not guaranteed. 304*8334SJose.Borrego@Sun.COM * 305*8334SJose.Borrego@Sun.COM * To deal with this, MSRPC sometimes uses an additional wrapper with two 306*8334SJose.Borrego@Sun.COM * more fields, as shown below. 307*8334SJose.Borrego@Sun.COM * length: the array length in bytes excluding terminating null bytes 308*8334SJose.Borrego@Sun.COM * maxlen: the array length in bytes including null terminator bytes 309*8334SJose.Borrego@Sun.COM * LPTSTR: converted to a string_t by NDR 310*8334SJose.Borrego@Sun.COM * 311*8334SJose.Borrego@Sun.COM * typedef struct ms_string { 312*8334SJose.Borrego@Sun.COM * WORD length; 313*8334SJose.Borrego@Sun.COM * WORD maxlen; 314*8334SJose.Borrego@Sun.COM * LPTSTR str; 315*8334SJose.Borrego@Sun.COM * } ms_string_t; 316*8334SJose.Borrego@Sun.COM */ 317*8334SJose.Borrego@Sun.COM typedef struct ndr_mstring { 318*8334SJose.Borrego@Sun.COM uint16_t length; 319*8334SJose.Borrego@Sun.COM uint16_t allosize; 320*8334SJose.Borrego@Sun.COM LPTSTR str; 321*8334SJose.Borrego@Sun.COM } ndr_mstring_t; 322*8334SJose.Borrego@Sun.COM 323*8334SJose.Borrego@Sun.COM /* 324*8334SJose.Borrego@Sun.COM * A number of heap areas are used during marshalling and unmarshalling. 325*8334SJose.Borrego@Sun.COM * Under some circumstances these areas can be discarded by the library 326*8334SJose.Borrego@Sun.COM * code, i.e. on the server side before returning to the client and on 327*8334SJose.Borrego@Sun.COM * completion of a client side bind. In the case of a client side RPC 328*8334SJose.Borrego@Sun.COM * call, these areas must be preserved after an RPC returns to give the 329*8334SJose.Borrego@Sun.COM * caller time to take a copy of the data. In this case the client must 330*8334SJose.Borrego@Sun.COM * call ndr_clnt_free_heap to free the memory. 331*8334SJose.Borrego@Sun.COM * 332*8334SJose.Borrego@Sun.COM * The heap management data definition looks a bit like this: 333*8334SJose.Borrego@Sun.COM * 334*8334SJose.Borrego@Sun.COM * heap -> +---------------+ +------------+ 335*8334SJose.Borrego@Sun.COM * | iovec[0].base | --> | data block | 336*8334SJose.Borrego@Sun.COM * | iovec[0].len | +------------+ 337*8334SJose.Borrego@Sun.COM * +---------------+ 338*8334SJose.Borrego@Sun.COM * :: 339*8334SJose.Borrego@Sun.COM * :: 340*8334SJose.Borrego@Sun.COM * iov -> +---------------+ +------------+ 341*8334SJose.Borrego@Sun.COM * | iovec[n].base | --> | data block | 342*8334SJose.Borrego@Sun.COM * | iovec[n].len | +------------+ 343*8334SJose.Borrego@Sun.COM * +---------------+ ^ ^ 344*8334SJose.Borrego@Sun.COM * | | 345*8334SJose.Borrego@Sun.COM * next ----------------------+ | 346*8334SJose.Borrego@Sun.COM * top -----------------------------------+ 347*8334SJose.Borrego@Sun.COM * 348*8334SJose.Borrego@Sun.COM */ 349*8334SJose.Borrego@Sun.COM 350*8334SJose.Borrego@Sun.COM /* 351*8334SJose.Borrego@Sun.COM * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes 352*8334SJose.Borrego@Sun.COM * of the first heap block. 353*8334SJose.Borrego@Sun.COM */ 354*8334SJose.Borrego@Sun.COM #define NDR_HEAP_MAXIOV 384 355*8334SJose.Borrego@Sun.COM #define NDR_HEAP_BLKSZ 8192 356*8334SJose.Borrego@Sun.COM 357*8334SJose.Borrego@Sun.COM typedef struct ndr_heap { 358*8334SJose.Borrego@Sun.COM struct iovec iovec[NDR_HEAP_MAXIOV]; 359*8334SJose.Borrego@Sun.COM struct iovec *iov; 360*8334SJose.Borrego@Sun.COM int iovcnt; 361*8334SJose.Borrego@Sun.COM char *top; 362*8334SJose.Borrego@Sun.COM char *next; 363*8334SJose.Borrego@Sun.COM } ndr_heap_t; 364*8334SJose.Borrego@Sun.COM 365*8334SJose.Borrego@Sun.COM /* 366*8334SJose.Borrego@Sun.COM * Alternate varying/conformant string definition 367*8334SJose.Borrego@Sun.COM * - for non-null-terminated strings. 368*8334SJose.Borrego@Sun.COM */ 369*8334SJose.Borrego@Sun.COM typedef struct ndr_vcs { 370*8334SJose.Borrego@Sun.COM /* 371*8334SJose.Borrego@Sun.COM * size_is (actually a copy of length_is) will 372*8334SJose.Borrego@Sun.COM * be inserted here by the marshalling library. 373*8334SJose.Borrego@Sun.COM */ 374*8334SJose.Borrego@Sun.COM uint32_t vc_first_is; 375*8334SJose.Borrego@Sun.COM uint32_t vc_length_is; 376*8334SJose.Borrego@Sun.COM uint16_t buffer[ANY_SIZE_ARRAY]; 377*8334SJose.Borrego@Sun.COM } ndr_vcs_t; 378*8334SJose.Borrego@Sun.COM 379*8334SJose.Borrego@Sun.COM typedef struct ndr_vcstr { 380*8334SJose.Borrego@Sun.COM uint16_t wclen; 381*8334SJose.Borrego@Sun.COM uint16_t wcsize; 382*8334SJose.Borrego@Sun.COM ndr_vcs_t *vcs; 383*8334SJose.Borrego@Sun.COM } ndr_vcstr_t; 384*8334SJose.Borrego@Sun.COM 385*8334SJose.Borrego@Sun.COM typedef struct ndr_vcb { 386*8334SJose.Borrego@Sun.COM /* 387*8334SJose.Borrego@Sun.COM * size_is (actually a copy of length_is) will 388*8334SJose.Borrego@Sun.COM * be inserted here by the marshalling library. 389*8334SJose.Borrego@Sun.COM */ 390*8334SJose.Borrego@Sun.COM uint32_t vc_first_is; 391*8334SJose.Borrego@Sun.COM uint32_t vc_length_is; 392*8334SJose.Borrego@Sun.COM uint8_t buffer[ANY_SIZE_ARRAY]; 393*8334SJose.Borrego@Sun.COM } ndr_vcb_t; 394*8334SJose.Borrego@Sun.COM 395*8334SJose.Borrego@Sun.COM typedef struct ndr_vcbuf { 396*8334SJose.Borrego@Sun.COM uint16_t len; 397*8334SJose.Borrego@Sun.COM uint16_t size; 398*8334SJose.Borrego@Sun.COM ndr_vcb_t *vcb; 399*8334SJose.Borrego@Sun.COM } ndr_vcbuf_t; 400*8334SJose.Borrego@Sun.COM 401*8334SJose.Borrego@Sun.COM ndr_heap_t *ndr_heap_create(void); 402*8334SJose.Borrego@Sun.COM void ndr_heap_destroy(ndr_heap_t *); 403*8334SJose.Borrego@Sun.COM void *ndr_heap_malloc(ndr_heap_t *, unsigned); 404*8334SJose.Borrego@Sun.COM void *ndr_heap_strdup(ndr_heap_t *, const char *); 405*8334SJose.Borrego@Sun.COM int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *); 406*8334SJose.Borrego@Sun.COM void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *); 407*8334SJose.Borrego@Sun.COM void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *); 408*8334SJose.Borrego@Sun.COM smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *); 409*8334SJose.Borrego@Sun.COM int ndr_heap_used(ndr_heap_t *); 410*8334SJose.Borrego@Sun.COM int ndr_heap_avail(ndr_heap_t *); 411*8334SJose.Borrego@Sun.COM 412*8334SJose.Borrego@Sun.COM #define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ) 413*8334SJose.Borrego@Sun.COM #define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T)) 414*8334SJose.Borrego@Sun.COM #define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N)) 415*8334SJose.Borrego@Sun.COM #define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S)) 416*8334SJose.Borrego@Sun.COM #define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT)) 417*8334SJose.Borrego@Sun.COM #define NDR_SIDDUP(XA, S) ndr_heap_siddup((XA)->heap, (S)) 418*8334SJose.Borrego@Sun.COM 419*8334SJose.Borrego@Sun.COM typedef struct ndr_xa { 420*8334SJose.Borrego@Sun.COM int fid; 421*8334SJose.Borrego@Sun.COM unsigned short ptype; /* high bits special */ 422*8334SJose.Borrego@Sun.COM unsigned short opnum; 423*8334SJose.Borrego@Sun.COM ndr_stream_t recv_nds; 424*8334SJose.Borrego@Sun.COM ndr_hdr_t recv_hdr; 425*8334SJose.Borrego@Sun.COM ndr_stream_t send_nds; 426*8334SJose.Borrego@Sun.COM ndr_hdr_t send_hdr; 427*8334SJose.Borrego@Sun.COM ndr_binding_t *binding; /* what we're using */ 428*8334SJose.Borrego@Sun.COM ndr_binding_t *binding_list; /* from connection */ 429*8334SJose.Borrego@Sun.COM ndr_heap_t *heap; 430*8334SJose.Borrego@Sun.COM ndr_pipe_t *pipe; 431*8334SJose.Borrego@Sun.COM } ndr_xa_t; 432*8334SJose.Borrego@Sun.COM 433*8334SJose.Borrego@Sun.COM /* 434*8334SJose.Borrego@Sun.COM * 20-byte opaque id used by various RPC services. 435*8334SJose.Borrego@Sun.COM */ 436*8334SJose.Borrego@Sun.COM CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t; 437*8334SJose.Borrego@Sun.COM 438*8334SJose.Borrego@Sun.COM typedef struct ndr_client { 439*8334SJose.Borrego@Sun.COM int (*xa_init)(struct ndr_client *, ndr_xa_t *); 440*8334SJose.Borrego@Sun.COM int (*xa_exchange)(struct ndr_client *, ndr_xa_t *); 441*8334SJose.Borrego@Sun.COM int (*xa_read)(struct ndr_client *, ndr_xa_t *); 442*8334SJose.Borrego@Sun.COM void (*xa_preserve)(struct ndr_client *, ndr_xa_t *); 443*8334SJose.Borrego@Sun.COM void (*xa_destruct)(struct ndr_client *, ndr_xa_t *); 444*8334SJose.Borrego@Sun.COM void (*xa_release)(struct ndr_client *); 445*8334SJose.Borrego@Sun.COM 446*8334SJose.Borrego@Sun.COM int fid; 447*8334SJose.Borrego@Sun.COM ndr_hdid_t *handle; 448*8334SJose.Borrego@Sun.COM ndr_binding_t *binding; 449*8334SJose.Borrego@Sun.COM ndr_binding_t *binding_list; 450*8334SJose.Borrego@Sun.COM ndr_binding_t binding_pool[NDR_N_BINDING_POOL]; 451*8334SJose.Borrego@Sun.COM 452*8334SJose.Borrego@Sun.COM boolean_t heap_preserved; 453*8334SJose.Borrego@Sun.COM ndr_heap_t *heap; 454*8334SJose.Borrego@Sun.COM ndr_stream_t *recv_nds; 455*8334SJose.Borrego@Sun.COM ndr_stream_t *send_nds; 456*8334SJose.Borrego@Sun.COM 457*8334SJose.Borrego@Sun.COM uint32_t next_call_id; 458*8334SJose.Borrego@Sun.COM unsigned next_p_cont_id; 459*8334SJose.Borrego@Sun.COM } ndr_client_t; 460*8334SJose.Borrego@Sun.COM 461*8334SJose.Borrego@Sun.COM typedef struct ndr_handle { 462*8334SJose.Borrego@Sun.COM ndr_hdid_t nh_id; 463*8334SJose.Borrego@Sun.COM struct ndr_handle *nh_next; 464*8334SJose.Borrego@Sun.COM int nh_fid; 465*8334SJose.Borrego@Sun.COM int nh_remote_os; 466*8334SJose.Borrego@Sun.COM const ndr_service_t *nh_svc; 467*8334SJose.Borrego@Sun.COM ndr_client_t *nh_clnt; 468*8334SJose.Borrego@Sun.COM void *nh_data; 469*8334SJose.Borrego@Sun.COM } ndr_handle_t; 470*8334SJose.Borrego@Sun.COM 471*8334SJose.Borrego@Sun.COM /* ndr_ops.c */ 472*8334SJose.Borrego@Sun.COM void nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *); 473*8334SJose.Borrego@Sun.COM void nds_finalize(ndr_stream_t *, ndr_fraglist_t *); 474*8334SJose.Borrego@Sun.COM void nds_destruct(ndr_stream_t *); 475*8334SJose.Borrego@Sun.COM 476*8334SJose.Borrego@Sun.COM /* ndr_client.c */ 477*8334SJose.Borrego@Sun.COM int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **); 478*8334SJose.Borrego@Sun.COM int ndr_clnt_call(ndr_binding_t *, int, void *); 479*8334SJose.Borrego@Sun.COM void ndr_clnt_free_heap(ndr_client_t *); 480*8334SJose.Borrego@Sun.COM 481*8334SJose.Borrego@Sun.COM /* ndr_marshal.c */ 482*8334SJose.Borrego@Sun.COM int ndr_encode_decode_common(ndr_xa_t *, int, unsigned, ndr_typeinfo_t *, 483*8334SJose.Borrego@Sun.COM void *); 484*8334SJose.Borrego@Sun.COM int ndr_decode_call(ndr_xa_t *, void *); 485*8334SJose.Borrego@Sun.COM int ndr_encode_return(ndr_xa_t *, void *); 486*8334SJose.Borrego@Sun.COM int ndr_encode_call(ndr_xa_t *, void *); 487*8334SJose.Borrego@Sun.COM int ndr_decode_return(ndr_xa_t *, void *); 488*8334SJose.Borrego@Sun.COM int ndr_decode_pdu_hdr(ndr_xa_t *); 489*8334SJose.Borrego@Sun.COM int ndr_encode_pdu_hdr(ndr_xa_t *); 490*8334SJose.Borrego@Sun.COM void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *); 491*8334SJose.Borrego@Sun.COM unsigned ndr_bind_ack_hdr_size(ndr_xa_t *); 492*8334SJose.Borrego@Sun.COM unsigned ndr_alter_context_rsp_hdr_size(void); 493*8334SJose.Borrego@Sun.COM 494*8334SJose.Borrego@Sun.COM /* ndr_server.c */ 495*8334SJose.Borrego@Sun.COM int ndr_pipe_open(int, uint8_t *, uint32_t); 496*8334SJose.Borrego@Sun.COM int ndr_pipe_close(int); 497*8334SJose.Borrego@Sun.COM int ndr_pipe_read(int, uint8_t *, uint32_t *, uint32_t *); 498*8334SJose.Borrego@Sun.COM int ndr_pipe_write(int, uint8_t *, uint32_t); 499*8334SJose.Borrego@Sun.COM 500*8334SJose.Borrego@Sun.COM int ndr_generic_call_stub(ndr_xa_t *); 501*8334SJose.Borrego@Sun.COM 502*8334SJose.Borrego@Sun.COM boolean_t ndr_is_admin(ndr_xa_t *); 503*8334SJose.Borrego@Sun.COM boolean_t ndr_is_poweruser(ndr_xa_t *); 504*8334SJose.Borrego@Sun.COM int32_t ndr_native_os(ndr_xa_t *); 505*8334SJose.Borrego@Sun.COM 506*8334SJose.Borrego@Sun.COM /* ndr_svc.c */ 507*8334SJose.Borrego@Sun.COM ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int); 508*8334SJose.Borrego@Sun.COM ndr_service_t *ndr_svc_lookup_name(const char *); 509*8334SJose.Borrego@Sun.COM ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int); 510*8334SJose.Borrego@Sun.COM int ndr_svc_register(ndr_service_t *); 511*8334SJose.Borrego@Sun.COM void ndr_svc_unregister(ndr_service_t *); 512*8334SJose.Borrego@Sun.COM void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int); 513*8334SJose.Borrego@Sun.COM ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t); 514*8334SJose.Borrego@Sun.COM ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *); 515*8334SJose.Borrego@Sun.COM 516*8334SJose.Borrego@Sun.COM int ndr_uuid_parse(char *, ndr_uuid_t *); 517*8334SJose.Borrego@Sun.COM void ndr_uuid_unparse(ndr_uuid_t *, char *); 518*8334SJose.Borrego@Sun.COM 519*8334SJose.Borrego@Sun.COM ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *); 520*8334SJose.Borrego@Sun.COM void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *); 521*8334SJose.Borrego@Sun.COM ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *); 522*8334SJose.Borrego@Sun.COM void ndr_hdclose(int fid); 523*8334SJose.Borrego@Sun.COM 524*8334SJose.Borrego@Sun.COM ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *); 5255331Samw 5265331Samw #ifdef __cplusplus 5275331Samw } 5285331Samw #endif 5295331Samw 5305331Samw #endif /* _LIBMLRPC_H */ 531