summaryrefslogtreecommitdiffstats
path: root/librpc/rpc/rpc_common.h
blob: 76557101dcda162029310be3b545f968c5fd3c94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
/*
   Unix SMB/CIFS implementation.

   Copyright (C) Stefan Metzmacher 2010-2011
   Copyright (C) Andrew Tridgell 2010-2011
   Copyright (C) Simo Sorce 2010

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __DEFAULT_LIBRPC_RPCCOMMON_H__
#define __DEFAULT_LIBRPC_RPCCOMMON_H__

#include "lib/util/data_blob.h"

#include "gen_ndr/dcerpc.h"
#include "lib/util/attr.h"

#include "librpc/ndr/libndr.h"

struct dcerpc_binding_handle;
struct GUID;
struct ndr_interface_table;
struct ndr_interface_call;
struct ndr_push;
struct ndr_pull;
struct ncacn_packet;
struct epm_floor;
struct epm_tower;
struct tevent_context;
struct tstream_context;
struct gensec_security;

enum dcerpc_transport_t {
	NCA_UNKNOWN, NCACN_NP, NCACN_IP_TCP, NCACN_IP_UDP, NCACN_VNS_IPC, 
	NCACN_VNS_SPP, NCACN_AT_DSP, NCADG_AT_DDP, NCALRPC, NCACN_UNIX_STREAM, 
	NCADG_UNIX_DGRAM, NCACN_HTTP, NCADG_IPX, NCACN_SPX, NCACN_INTERNAL };

/** this describes a binding to a particular transport/pipe */
struct dcerpc_binding;

/* dcerpc pipe flags */
#define DCERPC_DEBUG_PRINT_IN          (1<<0)
#define DCERPC_DEBUG_PRINT_OUT         (1<<1)
#define DCERPC_DEBUG_PRINT_BOTH (DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT)

#define DCERPC_DEBUG_VALIDATE_IN       (1<<2)
#define DCERPC_DEBUG_VALIDATE_OUT      (1<<3)
#define DCERPC_DEBUG_VALIDATE_BOTH (DCERPC_DEBUG_VALIDATE_IN | DCERPC_DEBUG_VALIDATE_OUT)

#define DCERPC_CONNECT                 (1<<4)
#define DCERPC_SIGN                    (1<<5)
#define DCERPC_SEAL                    (1<<6)

#define DCERPC_PUSH_BIGENDIAN          (1<<7)
#define DCERPC_PULL_BIGENDIAN          (1<<8)

#define DCERPC_SCHANNEL                (1<<9)

#define DCERPC_ANON_FALLBACK           (1<<10)

/* use a 128 bit session key */
#define DCERPC_SCHANNEL_128            (1<<12)

/* check incoming pad bytes */
#define DCERPC_DEBUG_PAD_CHECK         (1<<13)

/* set LIBNDR_FLAG_REF_ALLOC flag when decoding NDR */
#define DCERPC_NDR_REF_ALLOC           (1<<14)

#define DCERPC_AUTH_OPTIONS    (DCERPC_SEAL|DCERPC_SIGN|DCERPC_SCHANNEL|DCERPC_AUTH_SPNEGO|DCERPC_AUTH_KRB5|DCERPC_AUTH_NTLM)

/* select spnego auth */
#define DCERPC_AUTH_SPNEGO             (1<<15)

/* select krb5 auth */
#define DCERPC_AUTH_KRB5               (1<<16)

#define DCERPC_SMB2                    (1<<17)

/* select NTLM auth */
#define DCERPC_AUTH_NTLM               (1<<18)

/* this triggers the DCERPC_PFC_FLAG_CONC_MPX flag in the bind request */
#define DCERPC_CONCURRENT_MULTIPLEX     (1<<19)

/* this indicates DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag was negotiated */
#define DCERPC_HEADER_SIGNING          (1<<20)

/* use NDR64 transport */
#define DCERPC_NDR64                   (1<<21)

/* handle upgrades or downgrades automatically */
#define DCERPC_SCHANNEL_AUTO           (1<<23)

/* use aes schannel with hmac-sh256 session key */
#define DCERPC_SCHANNEL_AES            (1<<24)

/* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request */
#define DCERPC_PROPOSE_HEADER_SIGNING          (1<<25)

#define DCERPC_PACKET			(1<<26)

#define DCERPC_SMB1                    (1<<27)

/* The following definitions come from ../librpc/rpc/dcerpc_error.c  */

const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code);
uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status);

/* The following definitions come from ../librpc/rpc/binding.c  */

const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot);
struct dcerpc_binding *dcerpc_binding_dup(TALLOC_CTX *mem_ctx,
					  const struct dcerpc_binding *b);
NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx,
				    const struct dcerpc_binding *binding,
				    struct epm_tower *tower);
NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx,
				   struct epm_tower *tower,
				   struct dcerpc_binding **b_out);
NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out);
char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b);
struct GUID dcerpc_binding_get_object(const struct dcerpc_binding *b);
NTSTATUS dcerpc_binding_set_object(struct dcerpc_binding *b,
				   struct GUID object);
enum dcerpc_transport_t dcerpc_binding_get_transport(const struct dcerpc_binding *b);
NTSTATUS dcerpc_binding_set_transport(struct dcerpc_binding *b,
				      enum dcerpc_transport_t transport);
void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b,
				  enum dcerpc_AuthType *_auth_type,
				  enum dcerpc_AuthLevel *_auth_level);
uint32_t dcerpc_binding_get_assoc_group_id(const struct dcerpc_binding *b);
NTSTATUS dcerpc_binding_set_assoc_group_id(struct dcerpc_binding *b,
					   uint32_t assoc_group_id);
struct ndr_syntax_id dcerpc_binding_get_abstract_syntax(const struct dcerpc_binding *b);
NTSTATUS dcerpc_binding_set_abstract_syntax(struct dcerpc_binding *b,
					    const struct ndr_syntax_id *syntax);
const char *dcerpc_binding_get_string_option(const struct dcerpc_binding *b,
					     const char *name);
char *dcerpc_binding_copy_string_option(TALLOC_CTX *mem_ctx,
					const struct dcerpc_binding *b,
					const char *name);
NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b,
					  const char *name,
					  const char *value);
uint32_t dcerpc_binding_get_flags(const struct dcerpc_binding *b);
NTSTATUS dcerpc_binding_set_flags(struct dcerpc_binding *b,
				  uint32_t additional,
				  uint32_t clear);
NTSTATUS dcerpc_floor_get_uuid_full(const struct epm_floor *epm_floor, struct ndr_syntax_id *syntax);
const char *derpc_transport_string_by_transport(enum dcerpc_transport_t t);
enum dcerpc_transport_t dcerpc_transport_by_name(const char *name);
enum dcerpc_transport_t dcerpc_transport_by_tower(const struct epm_tower *tower);

/* The following definitions come from ../librpc/rpc/binding_handle.c  */

struct dcerpc_binding_handle_ops {
	const char *name;

	bool (*is_connected)(struct dcerpc_binding_handle *h);
	uint32_t (*set_timeout)(struct dcerpc_binding_handle *h,
				uint32_t timeout);

	void (*auth_info)(struct dcerpc_binding_handle *h,
			  enum dcerpc_AuthType *auth_type,
			  enum dcerpc_AuthLevel *auth_level);

	struct tevent_req *(*raw_call_send)(TALLOC_CTX *mem_ctx,
					    struct tevent_context *ev,
					    struct dcerpc_binding_handle *h,
					    const struct GUID *object,
					    uint32_t opnum,
					    uint32_t in_flags,
					    const uint8_t *in_data,
					    size_t in_length);
	NTSTATUS (*raw_call_recv)(struct tevent_req *req,
				  TALLOC_CTX *mem_ctx,
				  uint8_t **out_data,
				  size_t *out_length,
				  uint32_t *out_flags);

	struct tevent_req *(*disconnect_send)(TALLOC_CTX *mem_ctx,
					      struct tevent_context *ev,
					      struct dcerpc_binding_handle *h);
	NTSTATUS (*disconnect_recv)(struct tevent_req *req);

	/* TODO: remove the following functions */
	bool (*push_bigendian)(struct dcerpc_binding_handle *h);
	bool (*ref_alloc)(struct dcerpc_binding_handle *h);
	bool (*use_ndr64)(struct dcerpc_binding_handle *h);
	void (*do_ndr_print)(struct dcerpc_binding_handle *h,
			     ndr_flags_type ndr_flags,
			     const void *struct_ptr,
			     const struct ndr_interface_call *call);
	void (*ndr_push_failed)(struct dcerpc_binding_handle *h,
				NTSTATUS error,
				const void *struct_ptr,
				const struct ndr_interface_call *call);
	void (*ndr_pull_failed)(struct dcerpc_binding_handle *h,
				NTSTATUS error,
				const DATA_BLOB *blob,
				const struct ndr_interface_call *call);
	NTSTATUS (*ndr_validate_in)(struct dcerpc_binding_handle *h,
				    TALLOC_CTX *mem_ctx,
				    const DATA_BLOB *blob,
				    const struct ndr_interface_call *call);
	NTSTATUS (*ndr_validate_out)(struct dcerpc_binding_handle *h,
				     struct ndr_pull *pull_in,
				     const void *struct_ptr,
				     const struct ndr_interface_call *call);
};

struct dcerpc_binding_handle *_dcerpc_binding_handle_create(TALLOC_CTX *mem_ctx,
					const struct dcerpc_binding_handle_ops *ops,
					const struct GUID *object,
					const struct ndr_interface_table *table,
					void *pstate,
					size_t psize,
					const char *type,
					const char *location);
#define dcerpc_binding_handle_create(mem_ctx, ops, object, table, \
				state, type, location) \
	_dcerpc_binding_handle_create(mem_ctx, ops, object, table, \
				state, sizeof(type), #type, location)

void *_dcerpc_binding_handle_data(struct dcerpc_binding_handle *h);
#define dcerpc_binding_handle_data(_h, _type) \
	talloc_get_type_abort(_dcerpc_binding_handle_data(_h), _type)

_DEPRECATED_ void dcerpc_binding_handle_set_sync_ev(struct dcerpc_binding_handle *h,
						    struct tevent_context *ev);

bool dcerpc_binding_handle_is_connected(struct dcerpc_binding_handle *h);

uint32_t dcerpc_binding_handle_set_timeout(struct dcerpc_binding_handle *h,
					   uint32_t timeout);

void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h,
				     enum dcerpc_AuthType *auth_type,
				     enum dcerpc_AuthLevel *auth_level);

struct tevent_req *dcerpc_binding_handle_raw_call_send(TALLOC_CTX *mem_ctx,
						struct tevent_context *ev,
						struct dcerpc_binding_handle *h,
						const struct GUID *object,
						uint32_t opnum,
						uint32_t in_flags,
						const uint8_t *in_data,
						size_t in_length);
NTSTATUS dcerpc_binding_handle_raw_call_recv(struct tevent_req *req,
					     TALLOC_CTX *mem_ctx,
					     uint8_t **out_data,
					     size_t *out_length,
					     uint32_t *out_flags);
NTSTATUS dcerpc_binding_handle_raw_call(struct dcerpc_binding_handle *h,
					const struct GUID *object,
					uint32_t opnum,
					uint32_t in_flags,
					const uint8_t *in_data,
					size_t in_length,
					TALLOC_CTX *mem_ctx,
					uint8_t **out_data,
					size_t *out_length,
					uint32_t *out_flags);

struct tevent_req *dcerpc_binding_handle_disconnect_send(TALLOC_CTX *mem_ctx,
						struct tevent_context *ev,
						struct dcerpc_binding_handle *h);
NTSTATUS dcerpc_binding_handle_disconnect_recv(struct tevent_req *req);

struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
					struct tevent_context *ev,
					struct dcerpc_binding_handle *h,
					const struct GUID *object,
					const struct ndr_interface_table *table,
					uint32_t opnum,
					TALLOC_CTX *r_mem,
					void *r_ptr);
NTSTATUS dcerpc_binding_handle_call_recv(struct tevent_req *req);
NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h,
				    const struct GUID *object,
				    const struct ndr_interface_table *table,
				    uint32_t opnum,
				    TALLOC_CTX *r_mem,
				    void *r_ptr);

/**
 * Extract header information from a ncacn_packet
 * as a dcerpc_sec_vt_header2 as used by the security verification trailer.
 *
 * @param[in] pkt a packet
 *
 * @return a dcerpc_sec_vt_header2
 */
struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt);


/**
 * Test if two dcerpc_sec_vt_header2 structures are equal
 * without consideration of reserved fields.
 *
 * @param v1 a pointer to a dcerpc_sec_vt_header2 structure
 * @param v2 a pointer to a dcerpc_sec_vt_header2 structure
 *
 * @retval true if *v1 equals *v2
 */
bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1,
				 const struct dcerpc_sec_vt_header2 *v2);

/**
 * Check for consistency of the security verification trailer with the PDU header.
 * See <a href="http://msdn.microsoft.com/en-us/library/cc243559.aspx">MS-RPCE 2.2.2.13</a>.
 * A check with an empty trailer succeeds.
 *
 * @param[in] vt a pointer to the security verification trailer.
 * @param[in] bitmask1 which flags were negotiated on the connection.
 * @param[in] pcontext the syntaxes negotiated for the presentation context.
 * @param[in] header2 some fields from the PDU header.
 *
 * @retval true on success.
 */
bool dcerpc_sec_verification_trailer_check(
		const struct dcerpc_sec_verification_trailer *vt,
		const uint32_t *bitmask1,
		const struct dcerpc_sec_vt_pcontext *pcontext,
		const struct dcerpc_sec_vt_header2 *header2);

/**
 * @brief check and optionally extract the Bind Time Features from
 * the given ndr_syntax_id.
 *
 * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>.
 *
 * @param[in]  s the syntax that should be checked.
 *
 * @param[out] features This is optional, it will be filled with the extracted
 *                      features the on success, otherwise it's filled with 0.
 *
 * @return true if the syntax matches the 6CB71C2C-9812-4540 prefix with version 1, false otherwise.
 *
 * @see dcerpc_construct_bind_time_features
 */
bool dcerpc_extract_bind_time_features(struct ndr_syntax_id syntax, uint64_t *features);

/**
 * @brief Construct a ndr_syntax_id used for Bind Time Features Negotiation.
 *
 * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>.
 *
 * @param[in] features The supported features.
 *
 * @return The ndr_syntax_id with the given features.
 *
 * @see dcerpc_extract_bind_time_features
 */
struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features);

#define DCERPC_AUTH_PAD_LENGTH(stub_length) (\
	(((stub_length) % DCERPC_AUTH_PAD_ALIGNMENT) > 0)?\
	(DCERPC_AUTH_PAD_ALIGNMENT - (stub_length) % DCERPC_AUTH_PAD_ALIGNMENT):\
	0)

NTSTATUS dcerpc_generic_session_key(DATA_BLOB *session_key);

NTSTATUS dcerpc_ncacn_push_auth(DATA_BLOB *blob,
				TALLOC_CTX *mem_ctx,
				struct ncacn_packet *pkt,
				struct dcerpc_auth *auth_info);

void dcerpc_log_packet(const char *packet_log_dir,
		       const char *interface_name,
		       uint32_t opnum, ndr_flags_type flags,
		       const DATA_BLOB *pkt,
		       const char *why);

#ifdef DEVELOPER
void dcerpc_save_ndr_fuzz_seed(TALLOC_CTX *mem_ctx,
			       DATA_BLOB raw_blob,
			       const char *dump_dir,
			       const char *iface_name,
			       ndr_flags_type flags,
			       int opnum,
			       bool ndr64);
#else
static inline void dcerpc_save_ndr_fuzz_seed(TALLOC_CTX *mem_ctx,
					     DATA_BLOB raw_blob,
					     const char *dump_dir,
					     const char *iface_name,
					     ndr_flags_type flags,
					     int opnum,
					     bool ndr64)
{
	return;
}
#endif

#endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */