2 * Copyright (c) 2009 Secure Endpoints Inc.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 #define I_RpcGetBuffer MSRPC_I_GetBuffer
34 #define I_RpcFreeBuffer MSRPC_I_FreeBuffer
36 #define NdrServerInitializeNew MSRPC_NdrServerInitializeNew
38 /*! \brief Maximum size of an accepted message
40 This value is arbitrary. The chosen value is larger than the
41 maximum fragment size used by the SMB RPC transport and is only
42 meant to mitigate the damage that could be done from a malformed
45 #define MAX_RPC_MSG_SIZE 102400
47 /*! \brief Default message size */
48 #define DEF_RPC_MSG_SIZE 2048
50 /*! \brief Status of a msrpc_call object */
51 typedef enum msrpc_call_status {
53 MSRPC_CALL_MSGRECEIVED,
54 MSRPC_CALL_DISPATCHED,
55 MSRPC_CALL_MSGSENDING,
60 typedef enum PDU_type {
63 PDU_TYPE_RESPONSE = 2,
69 PDU_TYPE_CL_CANCEL = 8,
71 PDU_TYPE_CANCEL_ACK = 10,
73 PDU_TYPE_BIND_ACK = 12,
74 PDU_TYPE_BIND_NAK = 13,
75 PDU_TYPE_ALTER_CONTEXT = 14,
76 PDU_TYPE_ALTER_CONTEXT_RESP = 15,
77 PDU_TYPE_SHUTDOWN = 16,
78 PDU_TYPE_CO_CANCEL = 18,
79 PDU_TYPE_ORPHANED = 19
82 typedef enum msrpc_bind_reject_reason {
83 BIND_REJ_REASON_NOT_SPECIFIED = 0,
84 BIND_REJ_TEMPORARY_CONGESTION = 1,
85 BIND_REJ_LOCAL_LIMIT_EXCEEDED = 2,
86 BIND_REJ_CALLED_PADDR_UNKNOWN = 3, /* not used */
87 BIND_REJ_PROTOCOL_VERSION_NOT_SUPPORTED = 4,
88 BIND_REJ_DEFAULT_CONTEXT_NOT_SUPPORTED = 5, /* not used */
89 BIND_REJ_USER_DATA_NOT_READABLE = 6, /* not used */
90 BIND_REJ_NO_PSAP_AVAILABLE = 7 /* not used */
93 typedef unsigned __int8 byte;
94 typedef unsigned __int8 u_int8;
95 typedef unsigned __int16 u_int16;
96 typedef unsigned __int32 u_int32;
97 typedef unsigned __int64 u_int64;
99 /*! \brief Common RPC envelope header */
101 struct E_CommonHeader {
102 u_int8 rpc_vers; /*!< 00:01 RPC version == 5 */
103 u_int8 rpc_vers_minor; /*!< 01:01 minor version */
104 u_int8 PTYPE; /*!< 02:01 packet type */
105 u_int8 pfc_flags; /*!< 03:01 flags (see PFC_... ) */
107 #define PFC_FIRST_FRAG 0x01 /* First fragment */
108 #define PFC_LAST_FRAG 0x02 /* Last fragment */
109 #define PFC_PENDING_CANCEL 0x04 /* Cancel was pending at sender */
110 #define PFC_RESERVED_1 0x08
111 #define PFC_CONC_MPX 0x10 /* supports concurrent multiplexing
112 * of a single connection. */
113 #define PFC_DID_NOT_EXECUTE 0x20 /* only meaningful on `fault' packet;
114 * if true, guaranteed call did not
116 #define PFC_MAYBE 0x40 /* `maybe' call semantics requested */
117 #define PFC_OBJECT_UUID 0x80 /* if true, a non-nil object UUID
118 * was specified in the handle, and
119 * is present in the optional object
120 * field. If false, the object field
123 byte packed_drep[4]; /*!< 04:04 NDR data representation format label */
124 u_int16 frag_length; /*!< 08:02 total length of fragment */
125 u_int16 auth_length; /*!< 10:02 length of auth_value */
126 u_int32 call_id; /*!< 12:04 call identifier */
129 typedef u_int16 p_context_id_t; /* local context identifier */
131 /*! \brief RPC message buffer
133 typedef struct msrpc_buffer {
135 unsigned int buf_length;
136 unsigned int buf_alloc;
137 unsigned int buf_pos;
142 typedef struct cm_user cm_user_t;
146 A single RPC call. This might even be a single fragment of a
149 typedef struct msrpc_call {
150 struct msrpc_call * next;
151 struct msrpc_call * prev;
153 MSRPC_CALL_STATUS status;
155 u_int32 call_id; /*!< Call ID */
156 p_context_id_t context_id; /*!< presentation context ID (last seen) */
158 E_CommonHeader * in_header; /*!< Pointer to the header of the
159 input packet. Only valid during a
162 msrpc_buffer in; /*!< Input buffer */
164 msrpc_buffer out; /*!< Output buffer */
168 cm_user_t *cm_userp; /*!< Held reference to the cm_user_t
169 associated with this call. */
172 /*! \brief RPC connection structure
174 Represents a single RPC connection. Can support multiple queued
177 typedef struct _msrpc_conn {
178 unsigned int max_xmit_frag; /*!< Maximum size of fragment
180 unsigned int max_recv_frag; /*!< Maximum size of fragment
182 u_int32 assoc_group_id; /*!< Association group ID for the
185 unsigned int rpc_vers; /*!< RPC Protocol version. Always 5 */
186 unsigned int rpc_vers_minor; /*!< Minor version number. 0 or 1 */
188 char * secondary_address; /*!< Secondary address for the
191 RPC_SERVER_INTERFACE * interface;
192 /*!< Selected server interface. Only
193 valid after a successful bind. */
195 msrpc_call * head; /*!< Queue of msrpc_call objects for
205 MSRPC_Shutdown(void);
208 MSRPC_InitConn(msrpc_conn * conn, const char * secondary_address);
211 MSRPC_FreeConn(msrpc_conn * conn);
214 MSRPC_WriteMessage(msrpc_conn * conn, BYTE * buffer, unsigned int len,
218 MSRPC_PrepareRead(msrpc_conn * conn);
221 MSRPC_ReadMessageLength(msrpc_conn * conn, unsigned int max_len);
224 MSRPC_ReadMessage(msrpc_conn * conn, BYTE *buffer, unsigned int len);
228 I_RpcGetBuffer (IN OUT RPC_MESSAGE __RPC_FAR * Message);
232 I_RpcFreeBuffer (IN OUT RPC_MESSAGE __RPC_FAR * Message);
236 NdrServerInitializeNew(
237 PRPC_MESSAGE pRpcMsg,
238 PMIDL_STUB_MESSAGE pStubMsg,
239 PMIDL_STUB_DESC pStubDescriptor
243 MSRPC_GetCmUser(void);
245 extern void RPC_SRVSVC_Init(void);
247 extern void RPC_SRVSVC_Shutdown(void);
250 MSRPC_IsWellKnownService(const clientchar_t * lastNamep);