Changeset 920 for trunk/server/librpc
- Timestamp:
- Jun 9, 2016, 2:23:12 PM (9 years ago)
- Location:
- trunk/server
- Files:
-
- 12 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 919
- Property svn:mergeinfo changed
-
trunk/server/librpc/idl/dcerpc.idl
r862 r920 10 10 */ 11 11 import "misc.idl"; 12 13 cpp_quote("extern const uint8_t DCERPC_SEC_VT_MAGIC[8];") 12 14 13 15 interface dcerpc … … 454 456 455 457 /* pfc_flags values */ 456 const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */ 457 const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */ 458 const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */ 459 const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */ 460 const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */ 461 const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */ 462 const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */ 463 const uint8 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80; /* on valid guid is in the optional object field */ 458 typedef [bitmap8bit] bitmap { 459 DCERPC_PFC_FLAG_FIRST = 0x01, /* First fragment */ 460 DCERPC_PFC_FLAG_LAST = 0x02, /* Last fragment */ 461 DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING = 0x04, /* depends on the pdu type */ 462 DCERPC_PFC_FLAG_CONC_MPX = 0x10, /* supports concurrent multiplexing of a single connection. */ 463 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20, /* on a fault it means the server hasn't done anything */ 464 DCERPC_PFC_FLAG_MAYBE = 0x40, /* `maybe' call semantics requested */ 465 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80 /* on valid guid is in the optional object field */ 466 } dcerpc_pfc_flags; 467 468 /* Cancel was pending at sender */ 469 const int DCERPC_PFC_FLAG_PENDING_CANCEL = 470 DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING; 471 const ist DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = 472 DCERPC_PFC_FLAG_PENDING_CANCEL_OR_HDR_SIGNING; 464 473 465 474 /* these offsets are needed by the signing code */ … … 467 476 const uint8 DCERPC_DREP_OFFSET = 4; 468 477 const uint8 DCERPC_FRAG_LEN_OFFSET = 8; 478 const uint32 DCERPC_FRAG_MAX_SIZE = 5840; 469 479 const uint8 DCERPC_AUTH_LEN_OFFSET = 10; 470 480 const uint8 DCERPC_CALL_ID_OFFSET = 12; 481 const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16; 482 const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */ 471 483 472 484 /* little-endian flag */ … … 477 489 uint8 rpc_vers_minor; /* Minor version */ 478 490 dcerpc_pkt_type ptype; /* Packet type */ 479 uint8 pfc_flags;/* Fragmentation flags */491 dcerpc_pfc_flags pfc_flags; /* Fragmentation flags */ 480 492 uint8 drep[4]; /* NDR data representation */ 481 493 uint16 frag_length; /* Total length of fragment */ … … 507 519 [switch_is(ptype)] dcerpc_payload u; 508 520 } ncadg_packet; 521 522 typedef [bitmap16bit] bitmap { 523 DCERPC_SEC_VT_COMMAND_ENUM = 0x3FFF, 524 DCERPC_SEC_VT_COMMAND_END = 0x4000, 525 DCERPC_SEC_VT_MUST_PROCESS = 0x8000 526 } dcerpc_sec_vt_command; 527 528 typedef [enum16bit] enum { 529 DCERPC_SEC_VT_COMMAND_BITMASK1 = 0x0001, 530 DCERPC_SEC_VT_COMMAND_PCONTEXT = 0x0002, 531 DCERPC_SEC_VT_COMMAND_HEADER2 = 0x0003 532 } dcerpc_sec_vt_command_enum; 533 534 typedef [bitmap32bit] bitmap { 535 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING = 0x00000001 536 } dcerpc_sec_vt_bitmask1; 537 538 typedef struct { 539 ndr_syntax_id abstract_syntax; 540 ndr_syntax_id transfer_syntax; 541 } dcerpc_sec_vt_pcontext; 542 543 typedef struct { 544 dcerpc_pkt_type ptype; /* Packet type */ 545 [value(0)] uint8 reserved1; 546 [value(0)] uint16 reserved2; 547 uint8 drep[4]; /* NDR data representation */ 548 uint32 call_id; /* Call identifier */ 549 uint16 context_id; 550 uint16 opnum; 551 } dcerpc_sec_vt_header2; 552 553 typedef [switch_type(dcerpc_sec_vt_command_enum),nodiscriminant] union { 554 [case(DCERPC_SEC_VT_COMMAND_BITMASK1)] dcerpc_sec_vt_bitmask1 bitmask1; 555 [case(DCERPC_SEC_VT_COMMAND_PCONTEXT)] dcerpc_sec_vt_pcontext pcontext; 556 [case(DCERPC_SEC_VT_COMMAND_HEADER2)] dcerpc_sec_vt_header2 header2; 557 [default,flag(NDR_REMAINING)] DATA_BLOB _unknown; 558 } dcerpc_sec_vt_union; 559 560 typedef struct { 561 dcerpc_sec_vt_command command; 562 [switch_is(command & DCERPC_SEC_VT_COMMAND_ENUM)] 563 [subcontext(2),flag(NDR_SUBCONTEXT_NO_UNREAD_BYTES)] 564 dcerpc_sec_vt_union u; 565 } dcerpc_sec_vt; 566 567 typedef [public,nopush,nopull] struct { 568 uint16 count; 569 } dcerpc_sec_vt_count; 570 571 /* 572 * We assume that the whole verification trailer fits into 573 * the last 1024 bytes after the stub data. 574 * 575 * There're currently only 3 commands defined and each should 576 * only be used once. 577 */ 578 const uint16 DCERPC_SEC_VT_MAX_SIZE = 1024; 579 580 typedef [public,flag(NDR_PAHEX)] struct { 581 [flag(NDR_ALIGN4)] DATA_BLOB _pad; 582 [value(DCERPC_SEC_VT_MAGIC)] uint8 magic[8]; 583 dcerpc_sec_vt_count count; 584 dcerpc_sec_vt commands[count.count]; 585 } dcerpc_sec_verification_trailer; 509 586 } -
trunk/server/librpc/idl/idl_types.h
r918 r920 48 48 #define NDR_RELATIVE_REVERSE LIBNDR_FLAG_RELATIVE_REVERSE 49 49 #define NDR_NO_RELATIVE_REVERSE LIBNDR_FLAG_NO_RELATIVE_REVERSE 50 51 #define NDR_SUBCONTEXT_NO_UNREAD_BYTES LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES -
trunk/server/librpc/ndr/libndr.h
r918 r920 125 125 #define LIBNDR_STRING_FLAGS (0x7FFC) 126 126 127 /* 128 * don't debug NDR_ERR_BUFSIZE failures, 129 * as the available buffer might be incomplete. 130 * 131 * return NDR_ERR_INCOMPLETE_BUFFER instead. 132 */ 133 #define LIBNDR_FLAG_INCOMPLETE_BUFFER (1<<16) 134 135 /* 136 * This lets ndr_pull_subcontext_end() return 137 * NDR_ERR_UNREAD_BYTES. 138 */ 139 #define LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES (1<<17) 140 127 141 /* set if relative pointers should *not* be marshalled in reverse order */ 128 142 #define LIBNDR_FLAG_NO_RELATIVE_REVERSE (1<<18) … … 164 178 /* useful macro for debugging */ 165 179 #define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p) 180 #define NDR_PRINT_DEBUGC(dbgc_class, type, p) ndr_print_debugc(dbgc_class, (ndr_print_fn_t)ndr_print_ ##type, #p, p) 166 181 #define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_fn_t)ndr_print_ ##type, #p, level, p) 167 182 #define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p) … … 200 215 NDR_ERR_INVALID_POINTER, 201 216 NDR_ERR_UNREAD_BYTES, 202 NDR_ERR_NDR64 217 NDR_ERR_NDR64, 218 NDR_ERR_FLAGS, 219 NDR_ERR_INCOMPLETE_BUFFER 203 220 }; 204 221 … … 218 235 /* 219 236 flags passed to control parse flow 237 These are deliberately in a different range to the NDR_IN/NDR_OUT 238 flags to catch mixups 220 239 */ 221 #define NDR_SCALARS 1222 #define NDR_BUFFERS 2240 #define NDR_SCALARS 0x100 241 #define NDR_BUFFERS 0x200 223 242 224 243 /* 225 flags passed to ndr_print_*() 244 flags passed to ndr_print_*() and ndr pull/push for functions 245 These are deliberately in a different range to the NDR_SCALARS/NDR_BUFFERS 246 flags to catch mixups 226 247 */ 227 #define NDR_IN 1 228 #define NDR_OUT 2 229 #define NDR_BOTH 3 230 #define NDR_SET_VALUES 4 248 #define NDR_IN 0x10 249 #define NDR_OUT 0x20 250 #define NDR_BOTH 0x30 251 #define NDR_SET_VALUES 0x40 252 253 254 #define NDR_PULL_CHECK_FLAGS(ndr, ndr_flags) do { \ 255 if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) { \ 256 return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid pull struct ndr_flags 0x%x", ndr_flags); \ 257 } \ 258 } while (0) 259 260 #define NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags) do { \ 261 if ((ndr_flags) & ~(NDR_SCALARS|NDR_BUFFERS)) \ 262 return ndr_push_error(ndr, NDR_ERR_FLAGS, "Invalid push struct ndr_flags 0x%x", ndr_flags); \ 263 } while (0) 264 265 #define NDR_PULL_CHECK_FN_FLAGS(ndr, flags) do { \ 266 if ((flags) & ~(NDR_BOTH|NDR_SET_VALUES)) { \ 267 return ndr_pull_error(ndr, NDR_ERR_FLAGS, "Invalid fn pull flags 0x%x", flags); \ 268 } \ 269 } while (0) 270 271 #define NDR_PUSH_CHECK_FN_FLAGS(ndr, flags) do { \ 272 if ((flags) & ~(NDR_BOTH|NDR_SET_VALUES)) \ 273 return ndr_push_error(ndr, NDR_ERR_FLAGS, "Invalid fn push flags 0x%x", flags); \ 274 } while (0) 231 275 232 276 #define NDR_PULL_NEED_BYTES(ndr, n) do { \ 233 277 if (unlikely((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size)) { \ 278 if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \ 279 uint32_t _available = ndr->data_size - ndr->offset; \ 280 uint32_t _missing = n - _available; \ 281 ndr->relative_highest_offset = _missing; \ 282 } \ 234 283 return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull bytes %u (%s)", (unsigned)n, __location__); \ 235 284 } \ … … 248 297 } \ 249 298 if (unlikely(ndr->offset > ndr->data_size)) { \ 299 if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { \ 300 uint32_t _missing = ndr->offset - ndr->data_size; \ 301 ndr->relative_highest_offset = _missing; \ 302 } \ 250 303 return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull align %u", (unsigned)n); \ 251 304 } \ … … 403 456 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid); 404 457 bool ndr_syntax_id_equal(const struct ndr_syntax_id *i1, const struct ndr_syntax_id *i2); 458 char *ndr_syntax_id_to_string(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *id); 459 bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id); 405 460 enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p, ndr_push_flags_fn_t fn); 406 461 enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, uint32_t level, ndr_push_flags_fn_t fn); … … 425 480 size_t ndr_align_size(uint32_t offset, size_t n); 426 481 struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx); 482 enum ndr_err_code ndr_pull_append(struct ndr_pull *ndr, DATA_BLOB *blob); 483 enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr); 427 484 enum ndr_err_code ndr_pull_advance(struct ndr_pull *ndr, uint32_t size); 428 485 struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx); … … 430 487 enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_size); 431 488 void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3); 489 void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3); 432 490 void ndr_print_printf_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3); 433 491 void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3); 434 492 void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr); 493 void ndr_print_debugc(int dbgc_class, ndr_print_fn_t fn, const char *name, void *ptr); 435 494 void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr); 436 495 void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr); -
trunk/server/librpc/ndr/ndr.c
r918 r920 78 78 } 79 79 80 _PUBLIC_ enum ndr_err_code ndr_pull_append(struct ndr_pull *ndr, DATA_BLOB *blob) 81 { 82 enum ndr_err_code ndr_err; 83 DATA_BLOB b; 84 uint32_t append = 0; 85 bool ok; 86 87 if (blob->length == 0) { 88 return NDR_ERR_SUCCESS; 89 } 90 91 ndr_err = ndr_token_retrieve(&ndr->array_size_list, ndr, &append); 92 if (ndr_err == NDR_ERR_TOKEN) { 93 append = 0; 94 ndr_err = NDR_ERR_SUCCESS; 95 } 96 NDR_CHECK(ndr_err); 97 98 if (ndr->data_size == 0) { 99 ndr->data = NULL; 100 append = UINT32_MAX; 101 } 102 103 if (append == UINT32_MAX) { 104 /* 105 * append == UINT32_MAX means that 106 * ndr->data is either NULL or a valid 107 * talloc child of ndr, which means 108 * we can use data_blob_append() without 109 * data_blob_talloc() of the existing callers data 110 */ 111 b = data_blob_const(ndr->data, ndr->data_size); 112 } else { 113 b = data_blob_talloc(ndr, ndr->data, ndr->data_size); 114 if (b.data == NULL) { 115 return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__); 116 } 117 } 118 119 ok = data_blob_append(ndr, &b, blob->data, blob->length); 120 if (!ok) { 121 return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__); 122 } 123 124 ndr->data = b.data; 125 ndr->data_size = b.length; 126 127 return ndr_token_store(ndr, &ndr->array_size_list, ndr, UINT32_MAX); 128 } 129 130 _PUBLIC_ enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr) 131 { 132 uint32_t skip = 0; 133 uint32_t append = 0; 134 135 if (ndr->relative_base_offset != 0) { 136 return ndr_pull_error(ndr, NDR_ERR_RELATIVE, 137 "%s", __location__); 138 } 139 if (ndr->relative_highest_offset != 0) { 140 return ndr_pull_error(ndr, NDR_ERR_RELATIVE, 141 "%s", __location__); 142 } 143 if (ndr->relative_list != NULL) { 144 return ndr_pull_error(ndr, NDR_ERR_RELATIVE, 145 "%s", __location__); 146 } 147 if (ndr->relative_base_list != NULL) { 148 return ndr_pull_error(ndr, NDR_ERR_RELATIVE, 149 "%s", __location__); 150 } 151 152 /* 153 * we need to keep up to 7 bytes 154 * in order to get the aligment right. 155 */ 156 skip = ndr->offset & 0xFFFFFFF8; 157 158 if (skip == 0) { 159 return NDR_ERR_SUCCESS; 160 } 161 162 ndr->offset -= skip; 163 ndr->data_size -= skip; 164 165 append = ndr_token_peek(&ndr->array_size_list, ndr); 166 if (append != UINT32_MAX) { 167 /* 168 * here we assume, that ndr->data is not a 169 * talloc child of ndr. 170 */ 171 ndr->data += skip; 172 return NDR_ERR_SUCCESS; 173 } 174 175 memmove(ndr->data, ndr->data + skip, ndr->data_size); 176 177 ndr->data = talloc_realloc(ndr, ndr->data, uint8_t, ndr->data_size); 178 if (ndr->data_size != 0 && ndr->data == NULL) { 179 return ndr_pull_error(ndr, NDR_ERR_ALLOC, "%s", __location__); 180 } 181 182 return NDR_ERR_SUCCESS; 183 } 184 80 185 /* 81 186 advance by 'size' bytes … … 166 271 167 272 return NDR_ERR_SUCCESS; 273 } 274 275 _PUBLIC_ void ndr_print_debugc_helper(struct ndr_print *ndr, const char *format, ...) 276 { 277 va_list ap; 278 char *s = NULL; 279 uint32_t i; 280 int ret; 281 int dbgc_class; 282 283 va_start(ap, format); 284 ret = vasprintf(&s, format, ap); 285 va_end(ap); 286 287 if (ret == -1) { 288 return; 289 } 290 291 dbgc_class = *(int *)ndr->private_data; 292 293 if (ndr->no_newline) { 294 DEBUGADDC(dbgc_class, 1,("%s", s)); 295 free(s); 296 return; 297 } 298 299 for (i=0;i<ndr->depth;i++) { 300 DEBUGADDC(dbgc_class, 1,(" ")); 301 } 302 303 DEBUGADDC(dbgc_class, 1,("%s\n", s)); 304 free(s); 168 305 } 169 306 … … 236 373 "\n"); 237 374 } 375 } 376 377 /* 378 a useful helper function for printing idl structures via DEBUGC() 379 */ 380 _PUBLIC_ void ndr_print_debugc(int dbgc_class, ndr_print_fn_t fn, const char *name, void *ptr) 381 { 382 struct ndr_print *ndr; 383 384 DEBUGC(dbgc_class, 1,(" ")); 385 386 ndr = talloc_zero(NULL, struct ndr_print); 387 if (!ndr) return; 388 ndr->private_data = &dbgc_class; 389 ndr->print = ndr_print_debugc_helper; 390 ndr->depth = 1; 391 ndr->flags = 0; 392 fn(ndr, name, ptr); 393 talloc_free(ndr); 238 394 } 239 395 … … 403 559 va_list ap; 404 560 int ret; 561 562 if (ndr->flags & LIBNDR_FLAG_INCOMPLETE_BUFFER) { 563 switch (ndr_err) { 564 case NDR_ERR_BUFSIZE: 565 return NDR_ERR_INCOMPLETE_BUFFER; 566 default: 567 break; 568 } 569 } 405 570 406 571 va_start(ap, format); … … 558 723 break; 559 724 } 725 case 0xFFFFFFFF: 726 /* 727 * a shallow copy like subcontext 728 * useful for DCERPC pipe chunks. 729 */ 730 subndr = talloc_zero(ndr, struct ndr_pull); 731 NDR_ERR_HAVE_NO_MEMORY(subndr); 732 733 subndr->flags = ndr->flags; 734 subndr->current_mem_ctx = ndr->current_mem_ctx; 735 subndr->data = ndr->data; 736 subndr->offset = ndr->offset; 737 subndr->data_size = ndr->data_size; 738 739 *_subndr = subndr; 740 return NDR_ERR_SUCCESS; 741 560 742 default: 561 743 return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d", … … 590 772 { 591 773 uint32_t advance; 592 if (size_is >= 0) { 774 uint32_t highest_ofs; 775 776 if (header_size == 0xFFFFFFFF) { 777 advance = subndr->offset - ndr->offset; 778 } else if (size_is >= 0) { 593 779 advance = size_is; 594 780 } else if (header_size > 0) { … … 597 783 advance = subndr->offset; 598 784 } 785 786 if (subndr->offset > ndr->relative_highest_offset) { 787 highest_ofs = subndr->offset; 788 } else { 789 highest_ofs = subndr->relative_highest_offset; 790 } 791 if (!(subndr->flags & LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES)) { 792 /* 793 * avoid an error unless SUBCONTEXT_NO_UNREAD_BYTES is specified 794 */ 795 highest_ofs = advance; 796 } 797 if (highest_ofs < advance) { 798 return ndr_pull_error(subndr, NDR_ERR_UNREAD_BYTES, 799 "not all bytes consumed ofs[%u] advance[%u]", 800 highest_ofs, advance); 801 } 802 599 803 NDR_CHECK(ndr_pull_advance(ndr, advance)); 600 804 return NDR_ERR_SUCCESS; … … 1441 1645 { NDR_ERR_UNREAD_BYTES, "Unread Bytes" }, 1442 1646 { NDR_ERR_NDR64, "NDR64 assertion error" }, 1647 { NDR_ERR_INCOMPLETE_BUFFER, "Incomplete Buffer" }, 1443 1648 { 0, NULL } 1444 1649 }; -
trunk/server/librpc/ndr/ndr_basic.c
r918 r920 62 62 _PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v) 63 63 { 64 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 64 65 NDR_PULL_NEED_BYTES(ndr, 1); 65 66 *v = (int8_t)CVAL(ndr->data, ndr->offset); … … 73 74 _PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v) 74 75 { 76 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 75 77 NDR_PULL_NEED_BYTES(ndr, 1); 76 78 *v = CVAL(ndr->data, ndr->offset); … … 84 86 _PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v) 85 87 { 88 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 86 89 NDR_PULL_ALIGN(ndr, 2); 87 90 NDR_PULL_NEED_BYTES(ndr, 2); … … 96 99 _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v) 97 100 { 101 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 98 102 NDR_PULL_ALIGN(ndr, 2); 99 103 NDR_PULL_NEED_BYTES(ndr, 2); … … 108 112 _PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v) 109 113 { 114 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 110 115 if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) { 111 116 uint32_t v32 = 0; … … 126 131 _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v) 127 132 { 133 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 128 134 NDR_PULL_ALIGN(ndr, 4); 129 135 NDR_PULL_NEED_BYTES(ndr, 4); … … 138 144 _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v) 139 145 { 146 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 140 147 NDR_PULL_ALIGN(ndr, 4); 141 148 NDR_PULL_NEED_BYTES(ndr, 4); … … 152 159 uint64_t v64; 153 160 enum ndr_err_code err; 161 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 154 162 if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) { 155 163 return ndr_pull_uint32(ndr, ndr_flags, v); … … 170 178 _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v) 171 179 { 180 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 172 181 NDR_PULL_ALIGN(ndr, 8); 173 182 NDR_PULL_NEED_BYTES(ndr, 8); … … 218 227 _PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v) 219 228 { 229 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 220 230 NDR_PULL_ALIGN(ndr, 4); 221 231 NDR_PULL_NEED_BYTES(ndr, 8); … … 231 241 _PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v) 232 242 { 243 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 233 244 NDR_PULL_ALIGN(ndr, 4); 234 245 NDR_PULL_NEED_BYTES(ndr, 8); … … 265 276 { 266 277 uintptr_t h; 278 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 267 279 NDR_PULL_ALIGN(ndr, sizeof(h)); 268 280 NDR_PULL_NEED_BYTES(ndr, sizeof(h)); … … 279 291 { 280 292 uint32_t v; 293 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 281 294 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); 282 295 *status = NT_STATUS(v); … … 303 316 { 304 317 uint32_t v; 318 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 305 319 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); 306 320 *status = W_ERROR(v); … … 415 429 _PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n) 416 430 { 431 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 417 432 if (!(ndr_flags & NDR_SCALARS)) { 418 433 return NDR_ERR_SUCCESS; … … 426 441 _PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v) 427 442 { 443 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 428 444 NDR_PUSH_NEED_BYTES(ndr, 1); 429 445 SCVAL(ndr->data, ndr->offset, (uint8_t)v); … … 437 453 _PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v) 438 454 { 455 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 439 456 NDR_PUSH_NEED_BYTES(ndr, 1); 440 457 SCVAL(ndr->data, ndr->offset, v); … … 448 465 _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v) 449 466 { 467 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 450 468 NDR_PUSH_ALIGN(ndr, 2); 451 469 NDR_PUSH_NEED_BYTES(ndr, 2); … … 460 478 _PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v) 461 479 { 480 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 462 481 NDR_PUSH_ALIGN(ndr, 2); 463 482 NDR_PUSH_NEED_BYTES(ndr, 2); … … 483 502 _PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v) 484 503 { 504 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 485 505 NDR_PUSH_ALIGN(ndr, 4); 486 506 NDR_PUSH_NEED_BYTES(ndr, 4); … … 495 515 _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v) 496 516 { 517 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 497 518 NDR_PUSH_ALIGN(ndr, 4); 498 519 NDR_PUSH_NEED_BYTES(ndr, 4); … … 518 539 _PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v) 519 540 { 541 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 520 542 NDR_PUSH_ALIGN(ndr, 4); 521 543 NDR_PUSH_NEED_BYTES(ndr, 8); … … 531 553 _PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v) 532 554 { 555 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 533 556 NDR_PUSH_ALIGN(ndr, 4); 534 557 NDR_PUSH_NEED_BYTES(ndr, 8); … … 564 587 _PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v) 565 588 { 589 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 566 590 NDR_PUSH_ALIGN(ndr, 8); 567 591 NDR_PUSH_NEED_BYTES(ndr, 8); … … 577 601 { 578 602 uintptr_t h = (intptr_t)v; 603 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 579 604 NDR_PUSH_ALIGN(ndr, sizeof(h)); 580 605 NDR_PUSH_NEED_BYTES(ndr, sizeof(h)); … … 687 712 _PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n) 688 713 { 714 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 689 715 if (!(ndr_flags & NDR_SCALARS)) { 690 716 return NDR_ERR_SUCCESS; … … 739 765 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t) 740 766 { 767 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 741 768 NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t)); 742 769 return NDR_ERR_SUCCESS; … … 748 775 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t) 749 776 { 777 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 750 778 NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t)); 751 779 return NDR_ERR_SUCCESS; … … 757 785 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t) 758 786 { 787 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 759 788 t /= 10000000; 760 789 NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t)); … … 767 796 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t) 768 797 { 798 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 769 799 NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t)); 770 800 (*t) *= 10000000; … … 777 807 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t) 778 808 { 809 NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); 779 810 NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t)); 780 811 return NDR_ERR_SUCCESS; … … 786 817 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t) 787 818 { 819 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 788 820 NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t)); 789 821 return NDR_ERR_SUCCESS; … … 815 847 _PUBLIC_ enum ndr_err_code ndr_push_uid_t(struct ndr_push *ndr, int ndr_flags, uid_t u) 816 848 { 849 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 817 850 return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)u); 818 851 } … … 840 873 _PUBLIC_ enum ndr_err_code ndr_push_gid_t(struct ndr_push *ndr, int ndr_flags, gid_t g) 841 874 { 875 NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); 842 876 return ndr_push_hyper(ndr, NDR_SCALARS, (uint64_t)g); 843 877 } -
trunk/server/librpc/ndr/ndr_misc.c
r414 r920 36 36 && (i1->if_version == i2->if_version); 37 37 } 38 39 _PUBLIC_ char *ndr_syntax_id_to_string(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *id) 40 { 41 return talloc_asprintf(mem_ctx, 42 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/0x%08x", 43 id->uuid.time_low, id->uuid.time_mid, 44 id->uuid.time_hi_and_version, 45 id->uuid.clock_seq[0], 46 id->uuid.clock_seq[1], 47 id->uuid.node[0], id->uuid.node[1], 48 id->uuid.node[2], id->uuid.node[3], 49 id->uuid.node[4], id->uuid.node[5], 50 (unsigned)id->if_version); 51 } 52 53 _PUBLIC_ bool ndr_syntax_id_from_string(const char *s, struct ndr_syntax_id *id) 54 { 55 int ret; 56 size_t i; 57 uint32_t time_low; 58 uint32_t time_mid, time_hi_and_version; 59 uint32_t clock_seq[2]; 60 uint32_t node[6]; 61 uint32_t if_version; 62 63 ret = sscanf(s, 64 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x/0x%08x", 65 &time_low, &time_mid, &time_hi_and_version, 66 &clock_seq[0], &clock_seq[1], 67 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5], 68 &if_version); 69 if (ret != 12) { 70 return false; 71 } 72 73 id->uuid.time_low = time_low; 74 id->uuid.time_mid = time_mid; 75 id->uuid.time_hi_and_version = time_hi_and_version; 76 id->uuid.clock_seq[0] = clock_seq[0]; 77 id->uuid.clock_seq[1] = clock_seq[1]; 78 for (i=0; i<6; i++) { 79 id->uuid.node[i] = node[i]; 80 } 81 id->if_version = if_version; 82 83 return true; 84 } -
trunk/server/librpc/ndr/ndr_ntlmssp.c
r918 r920 177 177 } 178 178 179 _PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list, 180 enum ntlmssp_AvId AvId) 181 { 182 struct AV_PAIR *res = NULL; 183 uint32_t i = 0; 179 184 185 for (i = 0; i < av_list->count; i++) { 186 if (av_list->pair[i].AvId != AvId) { 187 continue; 188 } 189 190 res = discard_const_p(struct AV_PAIR, &av_list->pair[i]); 191 break; 192 } 193 194 return res; 195 } -
trunk/server/librpc/ndr/ndr_ntlmssp.h
r918 r920 32 32 _PUBLIC_ void ndr_print_ntlmssp_Version(struct ndr_print *ndr, const char *name, const union ntlmssp_Version *r); 33 33 34 _PUBLIC_ struct AV_PAIR *ndr_ntlmssp_find_av(const struct AV_PAIR_LIST *av_list, 35 enum ntlmssp_AvId AvId); -
trunk/server/librpc/rpc/dcerpc_util.c
r862 r920 28 28 #include "librpc/gen_ndr/ndr_dcerpc.h" 29 29 #include "rpc_common.h" 30 #include "lib/util/bitmap.h" 30 31 31 32 /* we need to be able to get/set the fragment length without doing a full … … 92 93 * @return - A NTSTATUS error code. 93 94 */ 94 NTSTATUS dcerpc_pull_auth_trailer( struct ncacn_packet *pkt,95 NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, 95 96 TALLOC_CTX *mem_ctx, 96 DATA_BLOB *pkt_trailer,97 const DATA_BLOB *pkt_trailer, 97 98 struct dcerpc_auth *auth, 98 uint32_t * auth_length,99 uint32_t *_auth_length, 99 100 bool auth_data_only) 100 101 { 101 102 struct ndr_pull *ndr; 102 103 enum ndr_err_code ndr_err; 103 uint32_t data_and_pad; 104 105 data_and_pad = pkt_trailer->length 106 - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length); 107 108 /* paranoia check for pad size. This would be caught anyway by 109 the ndr_pull_advance() a few lines down, but it scared 110 Jeremy enough for him to call me, so we might as well check 111 it now, just to prevent someone posting a bogus YouTube 112 video in the future. 113 */ 114 if (data_and_pad > pkt_trailer->length) { 115 return NT_STATUS_INFO_LENGTH_MISMATCH; 116 } 117 118 *auth_length = pkt_trailer->length - data_and_pad; 104 uint16_t data_and_pad; 105 uint16_t auth_length; 106 uint32_t tmp_length; 107 108 ZERO_STRUCTP(auth); 109 if (_auth_length != NULL) { 110 *_auth_length = 0; 111 } 112 113 /* Paranoia checks for auth_length. The caller should check this... */ 114 if (pkt->auth_length == 0) { 115 return NT_STATUS_INTERNAL_ERROR; 116 } 117 118 /* Paranoia checks for auth_length. The caller should check this... */ 119 if (pkt->auth_length > pkt->frag_length) { 120 return NT_STATUS_INTERNAL_ERROR; 121 } 122 tmp_length = DCERPC_NCACN_PAYLOAD_OFFSET; 123 tmp_length += DCERPC_AUTH_TRAILER_LENGTH; 124 tmp_length += pkt->auth_length; 125 if (tmp_length > pkt->frag_length) { 126 return NT_STATUS_INTERNAL_ERROR; 127 } 128 if (pkt_trailer->length > UINT16_MAX) { 129 return NT_STATUS_INTERNAL_ERROR; 130 } 131 132 auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length; 133 if (pkt_trailer->length < auth_length) { 134 return NT_STATUS_RPC_PROTOCOL_ERROR; 135 } 136 137 data_and_pad = pkt_trailer->length - auth_length; 119 138 120 139 ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx); … … 136 155 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 137 156 talloc_free(ndr); 157 ZERO_STRUCTP(auth); 138 158 return ndr_map_error2ntstatus(ndr_err); 139 159 } 140 160 141 if ( auth_data_only && data_and_pad !=auth->auth_pad_length) {142 DEBUG(1, (__location__ ": WARNING: pad length mismatch. "161 if (data_and_pad < auth->auth_pad_length) { 162 DEBUG(1, (__location__ ": ERROR: pad length mismatch. " 143 163 "Calculated %u got %u\n", 144 164 (unsigned)data_and_pad, 145 165 (unsigned)auth->auth_pad_length)); 166 talloc_free(ndr); 167 ZERO_STRUCTP(auth); 168 return NT_STATUS_RPC_PROTOCOL_ERROR; 169 } 170 171 if (auth_data_only && data_and_pad != auth->auth_pad_length) { 172 DEBUG(1, (__location__ ": ERROR: pad length mismatch. " 173 "Calculated %u got %u\n", 174 (unsigned)data_and_pad, 175 (unsigned)auth->auth_pad_length)); 176 talloc_free(ndr); 177 ZERO_STRUCTP(auth); 178 return NT_STATUS_RPC_PROTOCOL_ERROR; 146 179 } 147 180 … … 151 184 talloc_steal(mem_ctx, auth->credentials.data); 152 185 talloc_free(ndr); 186 187 if (_auth_length != NULL) { 188 *_auth_length = auth_length; 189 } 190 191 return NT_STATUS_OK; 192 } 193 194 /** 195 * @brief Verify the fields in ncacn_packet header. 196 * 197 * @param pkt - The ncacn_packet strcuture 198 * @param ptype - The expected PDU type 199 * @param max_auth_info - The maximum size of a possible auth trailer 200 * @param required_flags - The required flags for the pdu. 201 * @param optional_flags - The possible optional flags for the pdu. 202 * 203 * @return - A NTSTATUS error code. 204 */ 205 NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, 206 enum dcerpc_pkt_type ptype, 207 size_t max_auth_info, 208 uint8_t required_flags, 209 uint8_t optional_flags) 210 { 211 if (pkt->rpc_vers != 5) { 212 return NT_STATUS_RPC_PROTOCOL_ERROR; 213 } 214 215 if (pkt->rpc_vers_minor != 0) { 216 return NT_STATUS_RPC_PROTOCOL_ERROR; 217 } 218 219 if (pkt->auth_length > pkt->frag_length) { 220 return NT_STATUS_RPC_PROTOCOL_ERROR; 221 } 222 223 if (pkt->ptype != ptype) { 224 return NT_STATUS_RPC_PROTOCOL_ERROR; 225 } 226 227 if (max_auth_info > UINT16_MAX) { 228 return NT_STATUS_INTERNAL_ERROR; 229 } 230 231 if (pkt->auth_length > 0) { 232 size_t max_auth_length; 233 234 if (max_auth_info <= DCERPC_AUTH_TRAILER_LENGTH) { 235 return NT_STATUS_RPC_PROTOCOL_ERROR; 236 } 237 max_auth_length = max_auth_info - DCERPC_AUTH_TRAILER_LENGTH; 238 239 if (pkt->auth_length > max_auth_length) { 240 return NT_STATUS_RPC_PROTOCOL_ERROR; 241 } 242 } 243 244 if ((pkt->pfc_flags & required_flags) != required_flags) { 245 return NT_STATUS_RPC_PROTOCOL_ERROR; 246 } 247 if (pkt->pfc_flags & ~(optional_flags|required_flags)) { 248 return NT_STATUS_RPC_PROTOCOL_ERROR; 249 } 250 251 if (pkt->drep[0] & ~DCERPC_DREP_LE) { 252 return NT_STATUS_RPC_PROTOCOL_ERROR; 253 } 254 if (pkt->drep[1] != 0) { 255 return NT_STATUS_RPC_PROTOCOL_ERROR; 256 } 257 if (pkt->drep[2] != 0) { 258 return NT_STATUS_RPC_PROTOCOL_ERROR; 259 } 260 if (pkt->drep[3] != 0) { 261 return NT_STATUS_RPC_PROTOCOL_ERROR; 262 } 153 263 154 264 return NT_STATUS_OK; … … 342 452 return NT_STATUS_OK; 343 453 } 454 455 struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt) 456 { 457 struct dcerpc_sec_vt_header2 ret; 458 459 ZERO_STRUCT(ret); 460 ret.ptype = pkt->ptype; 461 memcpy(&ret.drep, pkt->drep, sizeof(ret.drep)); 462 ret.call_id = pkt->call_id; 463 464 switch (pkt->ptype) { 465 case DCERPC_PKT_REQUEST: 466 ret.context_id = pkt->u.request.context_id; 467 ret.opnum = pkt->u.request.opnum; 468 break; 469 470 case DCERPC_PKT_RESPONSE: 471 ret.context_id = pkt->u.response.context_id; 472 break; 473 474 case DCERPC_PKT_FAULT: 475 ret.context_id = pkt->u.fault.context_id; 476 break; 477 478 default: 479 break; 480 } 481 482 return ret; 483 } 484 485 bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1, 486 const struct dcerpc_sec_vt_header2 *v2) 487 { 488 if (v1->ptype != v2->ptype) { 489 return false; 490 } 491 492 if (memcmp(v1->drep, v2->drep, sizeof(v1->drep)) != 0) { 493 return false; 494 } 495 496 if (v1->call_id != v2->call_id) { 497 return false; 498 } 499 500 if (v1->context_id != v2->context_id) { 501 return false; 502 } 503 504 if (v1->opnum != v2->opnum) { 505 return false; 506 } 507 508 return true; 509 } 510 511 static bool dcerpc_sec_vt_is_valid(const struct dcerpc_sec_verification_trailer *r) 512 { 513 bool ret = false; 514 TALLOC_CTX *frame = talloc_stackframe(); 515 struct bitmap *commands_seen; 516 int i; 517 518 if (r->count.count == 0) { 519 ret = true; 520 goto done; 521 } 522 523 if (memcmp(r->magic, DCERPC_SEC_VT_MAGIC, sizeof(r->magic)) != 0) { 524 goto done; 525 } 526 527 commands_seen = bitmap_talloc(frame, DCERPC_SEC_VT_COMMAND_ENUM + 1); 528 if (commands_seen == NULL) { 529 goto done; 530 } 531 532 for (i=0; i < r->count.count; i++) { 533 enum dcerpc_sec_vt_command_enum cmd = 534 r->commands[i].command & DCERPC_SEC_VT_COMMAND_ENUM; 535 536 if (bitmap_query(commands_seen, cmd)) { 537 /* Each command must appear at most once. */ 538 goto done; 539 } 540 bitmap_set(commands_seen, cmd); 541 542 switch (cmd) { 543 case DCERPC_SEC_VT_COMMAND_BITMASK1: 544 case DCERPC_SEC_VT_COMMAND_PCONTEXT: 545 case DCERPC_SEC_VT_COMMAND_HEADER2: 546 break; 547 default: 548 if ((r->commands[i].u._unknown.length % 4) != 0) { 549 goto done; 550 } 551 break; 552 } 553 } 554 ret = true; 555 done: 556 TALLOC_FREE(frame); 557 return ret; 558 } 559 560 #define CHECK(msg, ok) \ 561 do { \ 562 if (!ok) { \ 563 DEBUG(10, ("SEC_VT check %s failed\n", msg)); \ 564 return false; \ 565 } \ 566 } while(0) 567 568 #define CHECK_SYNTAX(msg, s1, s2) \ 569 do { \ 570 if (!ndr_syntax_id_equal(&s1, &s2)) { \ 571 TALLOC_CTX *frame = talloc_stackframe(); \ 572 DEBUG(10, ("SEC_VT check %s failed: %s vs. %s\n", msg, \ 573 ndr_syntax_id_to_string(frame, &s1), \ 574 ndr_syntax_id_to_string(frame, &s1))); \ 575 TALLOC_FREE(frame); \ 576 return false; \ 577 } \ 578 } while(0) 579 580 581 bool dcerpc_sec_verification_trailer_check( 582 const struct dcerpc_sec_verification_trailer *vt, 583 const uint32_t *bitmask1, 584 const struct dcerpc_sec_vt_pcontext *pcontext, 585 const struct dcerpc_sec_vt_header2 *header2) 586 { 587 size_t i; 588 589 if (!dcerpc_sec_vt_is_valid(vt)) { 590 return false; 591 } 592 593 for (i=0; i < vt->count.count; i++) { 594 struct dcerpc_sec_vt *c = &vt->commands[i]; 595 596 switch (c->command & DCERPC_SEC_VT_COMMAND_ENUM) { 597 case DCERPC_SEC_VT_COMMAND_BITMASK1: 598 if (bitmask1 == NULL) { 599 CHECK("Bitmask1 must_process_command", 600 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 601 break; 602 } 603 604 if (c->u.bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING) { 605 CHECK("Bitmask1 client_header_signing", 606 *bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING); 607 } 608 break; 609 610 case DCERPC_SEC_VT_COMMAND_PCONTEXT: 611 if (pcontext == NULL) { 612 CHECK("Pcontext must_process_command", 613 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 614 break; 615 } 616 617 CHECK_SYNTAX("Pcontect abstract_syntax", 618 pcontext->abstract_syntax, 619 c->u.pcontext.abstract_syntax); 620 CHECK_SYNTAX("Pcontext transfer_syntax", 621 pcontext->transfer_syntax, 622 c->u.pcontext.transfer_syntax); 623 break; 624 625 case DCERPC_SEC_VT_COMMAND_HEADER2: { 626 if (header2 == NULL) { 627 CHECK("Header2 must_process_command", 628 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 629 break; 630 } 631 632 CHECK("Header2", dcerpc_sec_vt_header2_equal(header2, &c->u.header2)); 633 break; 634 } 635 636 default: 637 CHECK("Unknown must_process_command", 638 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 639 break; 640 } 641 } 642 643 return true; 644 } -
trunk/server/librpc/rpc/rpc_common.h
r862 r920 159 159 * @return - A NTSTATUS error code. 160 160 */ 161 NTSTATUS dcerpc_pull_auth_trailer( struct ncacn_packet *pkt,161 NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt, 162 162 TALLOC_CTX *mem_ctx, 163 DATA_BLOB *pkt_trailer,163 const DATA_BLOB *pkt_trailer, 164 164 struct dcerpc_auth *auth, 165 165 uint32_t *auth_length, 166 166 bool auth_data_only); 167 NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt, 168 enum dcerpc_pkt_type ptype, 169 size_t max_auth_info, 170 uint8_t required_flags, 171 uint8_t optional_flags); 167 172 struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx, 168 173 struct tevent_context *ev, … … 297 302 void *r_ptr); 298 303 304 /** 305 * Extract header information from a ncacn_packet 306 * as a dcerpc_sec_vt_header2 as used by the security verification trailer. 307 * 308 * @param[in] pkt a packet 309 * 310 * @return a dcerpc_sec_vt_header2 311 */ 312 struct dcerpc_sec_vt_header2 dcerpc_sec_vt_header2_from_ncacn_packet(const struct ncacn_packet *pkt); 313 314 315 /** 316 * Test if two dcerpc_sec_vt_header2 structures are equal 317 * without consideration of reserved fields. 318 * 319 * @param v1 a pointer to a dcerpc_sec_vt_header2 structure 320 * @param v2 a pointer to a dcerpc_sec_vt_header2 structure 321 * 322 * @retval true if *v1 equals *v2 323 */ 324 bool dcerpc_sec_vt_header2_equal(const struct dcerpc_sec_vt_header2 *v1, 325 const struct dcerpc_sec_vt_header2 *v2); 326 327 /** 328 * Check for consistency of the security verification trailer with the PDU header. 329 * See <a href="http://msdn.microsoft.com/en-us/library/cc243559.aspx">MS-RPCE 2.2.2.13</a>. 330 * A check with an empty trailer succeeds. 331 * 332 * @param[in] vt a pointer to the security verification trailer. 333 * @param[in] bitmask1 which flags were negotiated on the connection. 334 * @param[in] pcontext the syntaxes negotiatied for the presentation context. 335 * @param[in] header2 some fields from the PDU header. 336 * 337 * @retval true on success. 338 */ 339 bool dcerpc_sec_verification_trailer_check( 340 const struct dcerpc_sec_verification_trailer *vt, 341 const uint32_t *bitmask1, 342 const struct dcerpc_sec_vt_pcontext *pcontext, 343 const struct dcerpc_sec_vt_header2 *header2); 344 299 345 #endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */ -
trunk/server/librpc/wscript_build
r918 r920 275 275 276 276 bld.SAMBA_SUBSYSTEM('NDR_DCERPC', 277 source='gen_ndr/ndr_dcerpc.c ',277 source='gen_ndr/ndr_dcerpc.c ndr/ndr_dcerpc.c', 278 278 public_deps='ndr', 279 deps='bitmap', 279 280 public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h', 280 281 header_path= [ ('*gen_ndr*', 'gen_ndr') ],
Note:
See TracChangeset
for help on using the changeset viewer.